From 08d21d65ff3cfb3f181834801c3b276840247366 Mon Sep 17 00:00:00 2001 From: blnprasad Date: Fri, 7 May 2021 09:24:26 +0530 Subject: [PATCH 01/28] Make ping job workers channel buffer length same as len(servers) Original title: changes to avoid race condition seen with ping job workers (#32) Authored-by: blnprasad --- speedtest/speedtest.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/speedtest/speedtest.go b/speedtest/speedtest.go index b74934e..e4fbfbb 100644 --- a/speedtest/speedtest.go +++ b/speedtest/speedtest.go @@ -263,8 +263,8 @@ func SpeedTest(c *cli.Context) error { log.Info("Selecting the fastest server based on ping") var wg sync.WaitGroup - jobs := make(chan PingJob, 10) - results := make(chan PingResult, 10) + jobs := make(chan PingJob, len(servers)) + results := make(chan PingResult, len(servers)) done := make(chan struct{}) pingList := make(map[int]float64) From 9a8bca8fa028e4b1565fa5a79ec24c083f60f142 Mon Sep 17 00:00:00 2001 From: Cisco Cervellera <16772290+ciscoski@users.noreply.github.com> Date: Sat, 15 May 2021 14:24:05 +0100 Subject: [PATCH 02/28] Compatibility and Improved output (#34) * Added compatibility for cambridge-fibre backend GetIP for speedtest.cambridgefibre.uk retuns * a body which is not empty when queried with empty parameters * Just a string with IP informaiton (no distance) The code will not stop in this case but will printout a debug message. * Improved format for JSON and CSV output for multiple server. The JSON output is now a list of objects one per server. The CSV output has no empty rows. Co-authored-by: Cisco Cervellera --- defs/server.go | 6 +++++- speedtest/helper.go | 42 ++++++++++++++++++++++++------------------ 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/defs/server.go b/defs/server.go index 33417eb..370b826 100644 --- a/defs/server.go +++ b/defs/server.go @@ -60,8 +60,11 @@ func (s *Server) IsUp() bool { } defer resp.Body.Close() b, _ := ioutil.ReadAll(resp.Body) + if len(b) > 0 { + log.Debugf("Failed when parsing get IP result: %s", b) + } // only return online if the ping URL returns nothing and 200 - return len(b) == 0 && resp.StatusCode == http.StatusOK + return resp.StatusCode == http.StatusOK } // ICMPPingAndJitter pings the server via ICMP echos and calculate the average ping and jitter @@ -412,6 +415,7 @@ func (s *Server) GetIPInfo(distanceUnit string) (*GetIPResult, error) { if err := json.Unmarshal(b, &ipInfo); err != nil { log.Debugf("Failed when parsing get IP result: %s", err) log.Debugf("Received payload: %s", b) + ipInfo.ProcessedString = string(b[:]) } } diff --git a/speedtest/helper.go b/speedtest/helper.go index a357c66..fa8a408 100644 --- a/speedtest/helper.go +++ b/speedtest/helper.go @@ -32,6 +32,9 @@ func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.Tel log.Infof("Testing against %d servers", serverCount) } + var reps_json []report.JSONReport + var reps_csv []report.CSVReport + // fetch current user's IP info for _, currentServer := range servers { // get telemetry level @@ -140,8 +143,6 @@ func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.Tel // check for --csv or --json. the program prioritize the --csv before the --json. this is the same behavior as speedtest-cli if c.Bool(defs.OptionCSV) { // print csv if --csv is given - var reps []report.CSVReport - var rep report.CSVReport rep.Timestamp = time.Now() @@ -154,14 +155,7 @@ func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.Tel rep.Share = shareLink rep.IP = ispInfo.RawISPInfo.IP - reps = append(reps, rep) - - var buf bytes.Buffer - if err := gocsv.MarshalWithoutHeaders(&reps, &buf); err != nil { - log.Errorf("Error generating CSV report: %s", err) - } else { - log.Warn(buf.String()) - } + reps_csv = append(reps_csv, rep) } else if c.Bool(defs.OptionJSON) { // print json if --json is given var rep report.JSONReport @@ -180,23 +174,35 @@ func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.Tel rep.Client = report.Client{ispInfo.RawISPInfo} rep.Client.Readme = "" - - if b, err := json.Marshal(&rep); err != nil { - log.Errorf("Error generating JSON report: %s", err) - } else { - log.Warnf("%s", b) - } + + reps_json = append(reps_json,rep) } } else { log.Infof("Selected server %s (%s) is not responding at the moment, try again later", currentServer.Name, u.Hostname()) } - // add a new line after each test if testing multiple servers - if len(servers) > 1 { + //add a new line after each test if testing multiple servers + if ( len(servers) > 1 && !silent){ log.Warn() } } + // check for --csv or --json. the program prioritize the --csv before the --json. this is the same behavior as speedtest-cli + if c.Bool(defs.OptionCSV) { + var buf bytes.Buffer + if err := gocsv.MarshalWithoutHeaders(&reps_csv, &buf); err != nil { + log.Errorf("Error generating CSV report: %s", err) + } else { + log.Warn(buf.String()) + } + } else if c.Bool(defs.OptionJSON) { + if b, err := json.Marshal(&reps_json); err != nil { + log.Errorf("Error generating JSON report: %s", err) + } else { + log.Warnf("%s", b) + } + } + return nil } From 8e95ecefd7ad008cee53d7617805632d3d0625d7 Mon Sep 17 00:00:00 2001 From: Mka Madlavana Date: Mon, 5 Jul 2021 08:03:18 +0200 Subject: [PATCH 03/28] send --json and --csv results to stdout and logs to stderr (#39) --- main.go | 2 +- speedtest/helper.go | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/main.go b/main.go index c467b2f..fc4f23a 100644 --- a/main.go +++ b/main.go @@ -20,7 +20,7 @@ func init() { // warn level is for suppress modes // error level is for errors - log.SetOutput(os.Stdout) + log.SetOutput(os.Stderr) log.SetFormatter(formatter) log.SetLevel(log.InfoLevel) } diff --git a/speedtest/helper.go b/speedtest/helper.go index fa8a408..0aa5030 100644 --- a/speedtest/helper.go +++ b/speedtest/helper.go @@ -8,6 +8,7 @@ import ( "math" "mime/multipart" "net/http" + "os" "strconv" "strings" "time" @@ -193,13 +194,13 @@ func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.Tel if err := gocsv.MarshalWithoutHeaders(&reps_csv, &buf); err != nil { log.Errorf("Error generating CSV report: %s", err) } else { - log.Warn(buf.String()) + os.Stdout.WriteString(buf.String()) } } else if c.Bool(defs.OptionJSON) { if b, err := json.Marshal(&reps_json); err != nil { log.Errorf("Error generating JSON report: %s", err) } else { - log.Warnf("%s", b) + os.Stdout.Write(b[:]) } } From df77b3ee21b708f82a07c05fcbff990371e856be Mon Sep 17 00:00:00 2001 From: Dries Michiels <32487486+driesmp@users.noreply.github.com> Date: Tue, 18 Jan 2022 10:36:48 +0100 Subject: [PATCH 04/28] Use full link for the module directive in go.mod (#20) --- go.mod | 2 +- main.go | 4 ++-- report/json.go | 2 +- speedtest/helper.go | 4 ++-- speedtest/speedtest.go | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index ddc99a7..7cfa843 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module librespeed-cli +module github.com/librespeed/speedtest-cli go 1.14 diff --git a/main.go b/main.go index fc4f23a..97609cb 100644 --- a/main.go +++ b/main.go @@ -6,8 +6,8 @@ import ( log "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" - "librespeed-cli/defs" - "librespeed-cli/speedtest" + "github.com/librespeed/speedtest-cli/defs" + "github.com/librespeed/speedtest-cli/speedtest" ) // init sets up the essential bits on start up diff --git a/report/json.go b/report/json.go index a8e7dd7..fee05b3 100644 --- a/report/json.go +++ b/report/json.go @@ -3,7 +3,7 @@ package report import ( "time" - "librespeed-cli/defs" + "github.com/librespeed/speedtest-cli/defs" ) // JSONReport represents the output data fields in a JSON file diff --git a/speedtest/helper.go b/speedtest/helper.go index 0aa5030..27ecdf6 100644 --- a/speedtest/helper.go +++ b/speedtest/helper.go @@ -18,8 +18,8 @@ import ( log "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" - "librespeed-cli/defs" - "librespeed-cli/report" + "github.com/librespeed/speedtest-cli/defs" + "github.com/librespeed/speedtest-cli/report" ) const ( diff --git a/speedtest/speedtest.go b/speedtest/speedtest.go index e4fbfbb..94a5134 100644 --- a/speedtest/speedtest.go +++ b/speedtest/speedtest.go @@ -19,8 +19,8 @@ import ( log "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" - "librespeed-cli/defs" - "librespeed-cli/report" + "github.com/librespeed/speedtest-cli/defs" + "github.com/librespeed/speedtest-cli/report" ) const ( From c2af01baf5e0549957709b44d347693c07244485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6nning?= Date: Thu, 27 Jan 2022 12:26:47 +0100 Subject: [PATCH 05/28] Update Readme (#46) * Update Readme main.go Formatting README.md Formatting and update of Parameters added in the meantime. --no-icmp, --local-json, --duration, --chunks, --upload-size, --skip-cert-verify * Update README.md syntax --- README.md | 19 +++++++++++++++---- main.go | 6 +++--- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 7fe14a8..1654722 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,8 @@ GLOBAL OPTIONS: --ipv6, -6 Force IPv6 only (default: false) --no-download Do not perform download test (default: false) --no-upload Do not perform upload test (default: false) + --no-icmp Do not use ICMP ping. ICMP doesn't work well under Linux + at this moment, so you might want to disable it (default: false) --concurrent value Concurrent HTTP requests being made (default: 3) --bytes Display values in bytes instead of bits. Does not affect the image generated by --share, nor output from @@ -126,27 +128,32 @@ GLOBAL OPTIONS: --share Generate and provide a URL to the LibreSpeed.org share results image, not displayed with --csv (default: false) --simple Suppress verbose output, only show basic information - (default: false) + (default: false) --csv Suppress verbose output, only show basic information in CSV format. Speeds listed in bit/s and not affected by --bytes - (default: false) + (default: false) --csv-delimiter CSV_DELIMITER Single character delimiter (CSV_DELIMITER) to use in CSV output. (default: ",") --csv-header Print CSV headers (default: false) --json Suppress verbose output, only show basic information in JSON format. Speeds listed in bit/s and not - affected by --bytes (default: false) + affected by --bytes (default: false) --list Display a list of LibreSpeed.org servers (default: false) --server SERVER Specify a SERVER ID to test against. Can be supplied multiple times. Cannot be used with --exclude --exclude EXCLUDE EXCLUDE a server from selection. Can be supplied multiple times. Cannot be used with --server --server-json value Use an alternative server list from remote JSON file - --local-json value Use an alternative server list from local JSON file + --local-json value Use an alternative server list from local JSON file, + or read from stdin with "--local-json -". --source SOURCE SOURCE IP address to bind to --timeout TIMEOUT HTTP TIMEOUT in seconds. (default: 15) + --duration value Upload and download test duration in seconds (default: 15) + --chunks value Chunks to download from server, chunk size depends on server configuration (default: 100) + --upload-size value Size of payload being uploaded in KiB (default: 1024) --secure Use HTTPS instead of HTTP when communicating with LibreSpeed.org operated servers (default: false) + --skip-cert-verify Skip verifying SSL certificate for HTTPS connections (self-signed certs) (default: false) --no-pre-allocate Do not pre allocate upload data. Pre allocation is enabled by default to improve upload performance. To support systems with insufficient memory, use this @@ -190,6 +197,10 @@ locally via `--local-json`). The format is as below: ] ``` +The `--local-json` option can also read from `stdin`: + +`echo '[{"id": 1,"name": "a","server": "https://speedtest.example.com/","dlURL": "garbage.php","ulURL": "empty.php","pingURL": "empty.php","getIpURL": "getIP.php"}]' | librespeed-cli --local-json - ` + As you can see in the example, all servers have their schemes defined. In case of undefined scheme (e.g. `//example.com`), `librespeed-cli` will use `http` by default, or `https` when the `--secure` option is enabled. diff --git a/main.go b/main.go index 97609cb..a60b437 100644 --- a/main.go +++ b/main.go @@ -59,7 +59,7 @@ func main() { &cli.BoolFlag{ Name: defs.OptionNoICMP, Usage: "Do not use ICMP ping. ICMP doesn't work well under Linux\n" + - "at this moment, so you might want to disable it", + "\tat this moment, so you might want to disable it", }, &cli.IntFlag{ Name: defs.OptionConcurrent, @@ -110,7 +110,7 @@ func main() { Name: defs.OptionJSON, Usage: "Suppress verbose output, only show basic information\n" + "\tin JSON format. Speeds listed in bit/s and not\n" + - "\t affected by --bytes", + "\taffected by --bytes", }, &cli.BoolFlag{ Name: defs.OptionList, @@ -141,7 +141,7 @@ func main() { }, &cli.IntFlag{ Name: defs.OptionTimeout, - Usage: "HTTP `TIMEOUT` in seconds", + Usage: "HTTP `TIMEOUT` in seconds.", Value: 15, }, &cli.IntFlag{ From 954e973203c6068e8d0a45ae86baaa356d508f48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B6nning?= Date: Fri, 8 Jul 2022 18:43:19 +0200 Subject: [PATCH 06/28] Decimal places at jitter and ping. (#48) * Update README.md ups * stdout for --csv-header and --version Changed output type to stdout for --version and --csv-header. Addition to "send --json and --csv results to stdout and logs to stderr #39" * decimal places at jitter and ping better values with --share The browser version doesn't really seem to use decimal places at ping but this limits/extended ping and jitter to .2 decimal places at --csv / --json and stdout. this prevent 1.0909090909090908 ping times within csv and json and extend those values in rest of the data. The ping value could be adjusted to .0 to match the web version but this way the values are more accurate. +1 for the cli. * Update README.md Formatting adjusted --- README.md | 14 +++++++------- speedtest/helper.go | 20 ++++++++++---------- speedtest/speedtest.go | 3 ++- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 1654722..8228c50 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ For Linux users, you can use either the archive from golang.org, or install from ```shell script # pacman -S go ``` - + 2. Then, clone the repository: ```shell script @@ -59,10 +59,10 @@ can now proceed to build `librespeed-cli` with the build script: If you want to build for another operating system or system architecture, use the `GOOS` and `GOARCH` environment variables. Run `go tool dist list` to get a list of possible combinations of `GOOS` and `GOARCH`. - + Note: Technically, the CLI can be compiled with older Go versions that support Go modules, with `GO111MODULE=on` set. If you're compiling with an older Go runtime, you might have to change the Go version in `go.mod`. - + ```shell script # Let's say we're building for 64-bit Windows on Linux $ GOOS=windows GOARCH=amd64 ./build.sh @@ -74,7 +74,7 @@ can now proceed to build `librespeed-cli` with the build script: $ ls out librespeed-cli-windows-amd64.exe ``` - + 5. Now you can use the `librespeed-cli` and test your Internet speed! ## Install from AUR @@ -145,7 +145,7 @@ GLOBAL OPTIONS: multiple times. Cannot be used with --server --server-json value Use an alternative server list from remote JSON file --local-json value Use an alternative server list from local JSON file, - or read from stdin with "--local-json -". + or read from stdin with "--local-json -". --source SOURCE SOURCE IP address to bind to --timeout TIMEOUT HTTP TIMEOUT in seconds. (default: 15) --duration value Upload and download test duration in seconds (default: 15) @@ -153,7 +153,7 @@ GLOBAL OPTIONS: --upload-size value Size of payload being uploaded in KiB (default: 1024) --secure Use HTTPS instead of HTTP when communicating with LibreSpeed.org operated servers (default: false) - --skip-cert-verify Skip verifying SSL certificate for HTTPS connections (self-signed certs) (default: false) + --skip-cert-verify Skip verifying SSL certificate for HTTPS connections (self-signed certs) (default: false) --no-pre-allocate Do not pre allocate upload data. Pre allocation is enabled by default to improve upload performance. To support systems with insufficient memory, use this @@ -205,7 +205,7 @@ As you can see in the example, all servers have their schemes defined. In case o `librespeed-cli` will use `http` by default, or `https` when the `--secure` option is enabled. ## Use a custom telemetry server -By default, the telemetry result will be sent to `librespeed.org`. You can also customize your telemetry settings +By default, the telemetry result will be sent to `librespeed.org`. You can also customize your telemetry settings via the `--telemetry` prefixed options. In order to load a custom telemetry endpoint configuration, you'll have to use the `--telemetry-json` option to specify a local JSON file containing the configuration bits. The format is as below: diff --git a/speedtest/helper.go b/speedtest/helper.go index 27ecdf6..ddc9bc1 100644 --- a/speedtest/helper.go +++ b/speedtest/helper.go @@ -79,7 +79,7 @@ func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.Tel } if pb != nil { - pb.FinalMSG = fmt.Sprintf("Ping: %.0f ms\tJitter: %.0f ms\n", p, jitter) + pb.FinalMSG = fmt.Sprintf("Ping: %.2f ms\tJitter: %.2f ms\n", p, jitter) pb.Stop() } @@ -117,9 +117,9 @@ func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.Tel if c.Bool(defs.OptionSimple) { if c.Bool(defs.OptionBytes) { useMebi := c.Bool(defs.OptionMebiBytes) - log.Warnf("Ping:\t%.0f ms\tJitter:\t%.0f ms\nDownload rate:\t%s\nUpload rate:\t%s", p, jitter, humanizeMbps(downloadValue, useMebi), humanizeMbps(uploadValue, useMebi)) + log.Warnf("Ping:\t%.2f ms\tJitter:\t%.2f ms\nDownload rate:\t%s\nUpload rate:\t%s", p, jitter, humanizeMbps(downloadValue, useMebi), humanizeMbps(uploadValue, useMebi)) } else { - log.Warnf("Ping:\t%.0f ms\tJitter:\t%.0f ms\nDownload rate:\t%.2f Mbps\nUpload rate:\t%.2f Mbps", p, jitter, downloadValue, uploadValue) + log.Warnf("Ping:\t%.2f ms\tJitter:\t%.2f ms\nDownload rate:\t%.2f Mbps\nUpload rate:\t%.2f Mbps", p, jitter, downloadValue, uploadValue) } } @@ -149,7 +149,7 @@ func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.Tel rep.Name = currentServer.Name rep.Address = u.String() - rep.Ping = p + rep.Ping = math.Round(p*100) / 100 rep.Jitter = math.Round(jitter*100) / 100 rep.Download = math.Round(downloadValue*100) / 100 rep.Upload = math.Round(uploadValue*100) / 100 @@ -162,7 +162,7 @@ func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.Tel var rep report.JSONReport rep.Timestamp = time.Now() - rep.Ping = p + rep.Ping = math.Round(p*100) / 100 rep.Jitter = math.Round(jitter*100) / 100 rep.Download = math.Round(downloadValue*100) / 100 rep.Upload = math.Round(uploadValue*100) / 100 @@ -175,15 +175,15 @@ func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.Tel rep.Client = report.Client{ispInfo.RawISPInfo} rep.Client.Readme = "" - - reps_json = append(reps_json,rep) + + reps_json = append(reps_json, rep) } } else { log.Infof("Selected server %s (%s) is not responding at the moment, try again later", currentServer.Name, u.Hostname()) } //add a new line after each test if testing multiple servers - if ( len(servers) > 1 && !silent){ + if len(servers) > 1 && !silent { log.Warn() } } @@ -240,7 +240,7 @@ func sendTelemetry(telemetryServer defs.TelemetryServer, ispInfo *defs.GetIPResu if fPing, err := wr.CreateFormField("ping"); err != nil { log.Debugf("Error creating form field: %s", err) return "", err - } else if _, err = fPing.Write([]byte(strconv.Itoa(int(pingVal)))); err != nil { + } else if _, err = fPing.Write([]byte(strconv.FormatFloat(pingVal, 'f', 2, 64))); err != nil { log.Debugf("Error writing form field: %s", err) return "", err } @@ -248,7 +248,7 @@ func sendTelemetry(telemetryServer defs.TelemetryServer, ispInfo *defs.GetIPResu if fJitter, err := wr.CreateFormField("jitter"); err != nil { log.Debugf("Error creating form field: %s", err) return "", err - } else if _, err = fJitter.Write([]byte(strconv.Itoa(int(jitter)))); err != nil { + } else if _, err = fJitter.Write([]byte(strconv.FormatFloat(jitter, 'f', 2, 64))); err != nil { log.Debugf("Error writing form field: %s", err) return "", err } diff --git a/speedtest/speedtest.go b/speedtest/speedtest.go index 94a5134..159ef97 100644 --- a/speedtest/speedtest.go +++ b/speedtest/speedtest.go @@ -64,6 +64,7 @@ func SpeedTest(c *cli.Context) error { // print version if c.Bool(defs.OptionVersion) { + log.SetOutput(os.Stdout) log.Warnf("%s %s (built on %s)", defs.ProgName, defs.ProgVersion, defs.BuildDate) log.Warn("https://github.com/librespeed/speedtest-cli") log.Warn("Licensed under GNU Lesser General Public License v3.0") @@ -80,7 +81,7 @@ func SpeedTest(c *cli.Context) error { if c.Bool(defs.OptionCSVHeader) { var rep []report.CSVReport b, _ := gocsv.MarshalBytes(&rep) - log.Warnf("%s", b) + os.Stdout.WriteString(string(b)) return nil } From c996e515b18a783be6b988fe17eb587122b78e49 Mon Sep 17 00:00:00 2001 From: Daniel Brennand <52419383+dbrennand@users.noreply.github.com> Date: Fri, 8 Jul 2022 17:43:44 +0100 Subject: [PATCH 07/28] Feat/dockerfile (#47) * feat: Add dockerfile to run librespeed-cli in a container. * docs: Instructions to build and run container. --- README.md | 20 ++++++++++++++++++++ dockerfile | 17 +++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 dockerfile diff --git a/README.md b/README.md index 8228c50..816c1cf 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,26 @@ $ makepkg -si See the [librespeed-cli Homebrew tap](https://github.com/librespeed/homebrew-tap#setup). +## Container Image + +You can run `librespeed-cli` in a container. + +1. Build the container image: + + ```shell script + docker build -t librespeed-cli:latest . + ``` + +2. Run the container: + + ```shell script + docker run --rm --name librespeed-cli librespeed-cli:latest + # With options + docker run --rm --name librespeed-cli librespeed-cli:latest --telemetry-level disabled --no-upload + # To avoid "Failed to ping target host: socket: permission denied" errors when using --verbose + docker run --rm --name librespeed-cli --sysctl net.ipv4.ping_group_range="0 2147483647" librespeed-cli:latest --verbose + ``` + ## Usage You can see the full list of supported options with `librespeed-cli -h`: diff --git a/dockerfile b/dockerfile new file mode 100644 index 0000000..11ae38d --- /dev/null +++ b/dockerfile @@ -0,0 +1,17 @@ +FROM golang:1.17.7-buster as builder + +# Set working directory +WORKDIR /usr/src/librespeed-cli + +# Copy librespeed-cli +COPY . . + +# Build librespeed-cli +RUN ./build.sh + +FROM golang:1.17.7-buster + +# Copy librespeed-cli binary +COPY --from=builder /usr/src/librespeed-cli/out/librespeed-cli* /usr/src/librespeed-cli/librespeed-cli + +ENTRYPOINT ["/usr/src/librespeed-cli/librespeed-cli"] From af2908a51dbb66940d42d10282024ada424e1229 Mon Sep 17 00:00:00 2001 From: Maddie Zhan Date: Sat, 9 Jul 2022 00:50:40 +0800 Subject: [PATCH 08/28] goreleaser: don't upx compress Linux MIPS binaries --- .goreleaser.yml | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 3b347f3..86ea623 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -21,17 +21,10 @@ builds: - amd64 - arm - arm64 - - mips - - mipsle - - mips64 - - mips64le goarm: - 5 - 6 - 7 - gomips: - - hardfloat - - softfloat ignore: - goos: darwin goarch: 386 @@ -48,13 +41,27 @@ builds: ldflags: - -w -s -X "librespeed-cli/defs.ProgName={{ .ProjectName }}" -X "librespeed-cli/defs.ProgVersion=v{{ .Version }}" -X "librespeed-cli/defs.BuildDate={{ .Date }}" goos: + - linux - windows - darwin goarch: - 386 - amd64 - arm64 + - mips + - mipsle + - mips64 + - mips64le + gomips: + - hardfloat + - softfloat ignore: + - goos: linux + goarch: 386 + - goos: linux + goarch: amd64 + - goos: linux + goarch: arm64 - goos: darwin goarch: 386 - goos: darwin From 0f908e806c04c300bcaf14304dc4c3b3ce8e6e06 Mon Sep 17 00:00:00 2001 From: tech189 Date: Thu, 21 Jul 2022 15:22:45 +0100 Subject: [PATCH 09/28] Add Windows installation options to README (#54) --- README.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 816c1cf..c9f7dff 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ![LibreSpeed Logo](https://github.com/librespeed/speedtest/blob/master/.logo/logo3.png?raw=true) # LibreSpeed command line tool -Don't have a GUI but wants to use LibreSpeed servers to test your Internet speed? 🚀 +Don't have a GUI but want to use LibreSpeed servers to test your Internet speed? 🚀 `librespeed-cli` comes to rescue! @@ -97,6 +97,20 @@ $ makepkg -si See the [librespeed-cli Homebrew tap](https://github.com/librespeed/homebrew-tap#setup). +## Install on Windows + +If you have either [Scoop](https://scoop.sh/) or [Chocolatey](https://chocolatey.org/) installed you can use one of the following commands: + +- Scoop (ensure you have the `extras` bucket added): + ``` + > scoop install librespeed-cli + ``` + +- Chocolatey: + ``` + > choco install librespeed-cli + ``` + ## Container Image You can run `librespeed-cli` in a container. From 092760f344039e39b6ef8b91c3917a6c1ca1fd53 Mon Sep 17 00:00:00 2001 From: Mka Madlavana Date: Sat, 23 Jul 2022 14:21:18 +0200 Subject: [PATCH 10/28] throw an error if the specified --server is not in server list (#56) --- speedtest/speedtest.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/speedtest/speedtest.go b/speedtest/speedtest.go index 159ef97..8a68092 100644 --- a/speedtest/speedtest.go +++ b/speedtest/speedtest.go @@ -454,6 +454,10 @@ func preprocessServers(servers []defs.Server, forceHTTPS bool, excludes, specifi ret = append(ret, server) } } + if len(ret) == 0 { + error_message := fmt.Sprintf("specified server(s) not found: %v", specific) + return nil, errors.New(error_message) + } return ret, nil } } From 24b7826d78456728c5ab215d79ebd6d08fa4506e Mon Sep 17 00:00:00 2001 From: Mkhanyisi Madlavana Date: Tue, 10 Sep 2024 16:51:43 +0200 Subject: [PATCH 11/28] make `--version` to report the binary version again (#58) --- build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.sh b/build.sh index ca51d85..b06797a 100755 --- a/build.sh +++ b/build.sh @@ -10,9 +10,10 @@ CURRENT_DIR=$(pwd) OUT_DIR=${CURRENT_DIR}/out PROGNAME="librespeed-cli" +DEFS_PATH="github.com/librespeed/speedtest-cli" BINARY=${PROGNAME}-$(go env GOOS)-$(go env GOARCH) BUILD_DATE=$(date -u "+%Y-%m-%d %H:%M:%S %Z") -LDFLAGS="-w -s -X \"librespeed-cli/defs.ProgName=${PROGNAME}\" -X \"librespeed-cli/defs.ProgVersion=${PROGVER}\" -X \"librespeed-cli/defs.BuildDate=${BUILD_DATE}\"" +LDFLAGS="-w -s -X \"${DEFS_PATH}/defs.ProgName=${PROGNAME}\" -X \"${DEFS_PATH}/defs.ProgVersion=${PROGVER}\" -X \"${DEFS_PATH}/defs.BuildDate=${BUILD_DATE}\"" if [[ -n "${GOARM}" ]] && [[ "${GOARM}" -gt 0 ]]; then BINARY=${BINARY}v${GOARM} From 6059f16e57ea9c9cb89a5ee46fa1c9065e316277 Mon Sep 17 00:00:00 2001 From: czechbol Date: Tue, 10 Sep 2024 16:51:57 +0200 Subject: [PATCH 12/28] Updated dependencies (#62) * updated dependencies * fixed goreleaser config errors * formatted goreleaser config --- .goreleaser.yml | 130 ++++++++++++++++++++++++------------------------ go.mod | 21 ++++---- go.sum | 68 +++++++++++++++++++++++++ 3 files changed, 145 insertions(+), 74 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 86ea623..44b08eb 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,79 +1,81 @@ -project_name: 'librespeed-cli' +project_name: "librespeed-cli" #dist: ./out before: hooks: - go mod download builds: -- main: ./main.go - id: upx - env: - - CGO_ENABLED=0 - flags: - - -trimpath - ldflags: - - -w -s -X "librespeed-cli/defs.ProgName={{ .ProjectName }}" -X "librespeed-cli/defs.ProgVersion=v{{ .Version }}" -X "librespeed-cli/defs.BuildDate={{ .Date }}" - goos: - - linux - - darwin - - freebsd - goarch: - - 386 - - amd64 - - arm - - arm64 - goarm: - - 5 - - 6 - - 7 - ignore: - - goos: darwin - goarch: 386 - - goos: darwin - goarch: arm64 - hooks: - post: ./upx.sh -9 "{{ .Path }}" -- main: ./main.go - id: no-upx - env: - - CGO_ENABLED=0 - flags: - - -trimpath - ldflags: - - -w -s -X "librespeed-cli/defs.ProgName={{ .ProjectName }}" -X "librespeed-cli/defs.ProgVersion=v{{ .Version }}" -X "librespeed-cli/defs.BuildDate={{ .Date }}" - goos: - - linux - - windows - - darwin - goarch: - - 386 - - amd64 - - arm64 - - mips - - mipsle - - mips64 - - mips64le - gomips: - - hardfloat - - softfloat - ignore: - - goos: linux - goarch: 386 - - goos: linux - goarch: amd64 - - goos: linux - goarch: arm64 - - goos: darwin - goarch: 386 - - goos: darwin - goarch: amd64 + - main: ./main.go + id: upx + env: + - CGO_ENABLED=0 + flags: + - -trimpath + ldflags: + - -w -s -X "librespeed-cli/defs.ProgName={{ .ProjectName }}" -X "librespeed-cli/defs.ProgVersion=v{{ .Version }}" -X "librespeed-cli/defs.BuildDate={{ .Date }}" + goos: + - linux + - darwin + - freebsd + goarch: + - "386" + - amd64 + - arm + - arm64 + goarm: + - "5" + - "6" + - "7" + ignore: + - goos: darwin + goarch: "386" + - goos: darwin + goarch: arm64 + hooks: + post: + - ./upx.sh -9 "{{ .Path }}" + - main: ./main.go + id: no-upx + env: + - CGO_ENABLED=0 + flags: + - -trimpath + ldflags: + - -w -s -X "librespeed-cli/defs.ProgName={{ .ProjectName }}" -X "librespeed-cli/defs.ProgVersion=v{{ .Version }}" -X "librespeed-cli/defs.BuildDate={{ .Date }}" + goos: + - linux + - windows + - darwin + goarch: + - "386" + - amd64 + - arm64 + - mips + - mipsle + - mips64 + - mips64le + gomips: + - hardfloat + - softfloat + ignore: + - goos: linux + goarch: "386" + - goos: linux + goarch: amd64 + - goos: linux + goarch: arm64 + - goos: darwin + goarch: "386" + - goos: darwin + goarch: amd64 archives: - format_overrides: - goos: windows format: zip files: - LICENSE + rlcp: true checksum: - name_template: 'checksums.txt' + name_template: "checksums.txt" changelog: skip: false sort: asc diff --git a/go.mod b/go.mod index 7cfa843..fb1f268 100644 --- a/go.mod +++ b/go.mod @@ -3,15 +3,16 @@ module github.com/librespeed/speedtest-cli go 1.14 require ( - github.com/briandowns/spinner v1.12.0 - github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect - github.com/fatih/color v1.10.0 // indirect - github.com/go-ping/ping v0.0.0-20210407214646-e4e642a95741 - github.com/gocarina/gocsv v0.0.0-20210408192840-02d7211d929d + github.com/briandowns/spinner v1.23.0 + github.com/fatih/color v1.15.0 // indirect + github.com/go-ping/ping v1.1.0 + github.com/gocarina/gocsv v0.0.0-20230406101422-6445c2b15027 + github.com/google/uuid v1.3.0 // indirect + github.com/mattn/go-isatty v0.0.18 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sirupsen/logrus v1.8.1 - github.com/stretchr/testify v1.3.0 // indirect - github.com/urfave/cli/v2 v2.3.0 - golang.org/x/net v0.0.0-20210421230115-4e50805a0758 // indirect - golang.org/x/sys v0.0.0-20210421221651-33663a62ff08 // indirect + github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect + github.com/sirupsen/logrus v1.9.0 + github.com/urfave/cli/v2 v2.25.1 + golang.org/x/net v0.9.0 // indirect + gopkg.in/yaml.v2 v2.2.3 // indirect ) diff --git a/go.sum b/go.sum index cb424de..d8b8382 100644 --- a/go.sum +++ b/go.sum @@ -1,25 +1,45 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/briandowns/spinner v1.12.0 h1:72O0PzqGJb6G3KgrcIOtL/JAGGZ5ptOMCn9cUHmqsmw= github.com/briandowns/spinner v1.12.0/go.mod h1:QOuQk7x+EaDASo80FEXwlwiA+j/PPIcX3FScO+3/ZPQ= +github.com/briandowns/spinner v1.23.0 h1:alDF2guRWqa/FOZZYWjlMIx2L6H0wyewPxo/CH4Pt2A= +github.com/briandowns/spinner v1.23.0/go.mod h1:rPG4gmXeN3wQV/TsAY4w8lPdIM6RX3yqeBQJSrbXjuE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/go-ping/ping v0.0.0-20210407214646-e4e642a95741 h1:b0sLP++Tsle+s57tqg5sUk1/OQsC6yMCciVeqNzOcwU= github.com/go-ping/ping v0.0.0-20210407214646-e4e642a95741/go.mod h1:35JbSyV/BYqHwwRA6Zr1uVDm1637YlNOU61wI797NPI= +github.com/go-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw= +github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk= github.com/gocarina/gocsv v0.0.0-20210408192840-02d7211d929d h1:r3mStZSyjKhEcgbJ5xtv7kT5PZw/tDiFBTMgQx2qsXE= github.com/gocarina/gocsv v0.0.0-20210408192840-02d7211d929d/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI= +github.com/gocarina/gocsv v0.0.0-20230406101422-6445c2b15027 h1:LCGzZb4kMUUjMUzLxxqSJBwo9szUO0tK8cOxnEOT4Jc= +github.com/gocarina/gocsv v0.0.0-20230406101422-6445c2b15027/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= +github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -28,18 +48,41 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= +github.com/urfave/cli/v2 v2.25.1 h1:zw8dSP7ghX0Gmm8vugrs6q9Ku0wzweqPyshy+syu9Gw= +github.com/urfave/cli/v2 v2.25.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210421230115-4e50805a0758 h1:aEpZnXcAmXkd6AvLb2OPt+EN1Zu/8Ne3pCqPjja5PXY= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -48,12 +91,37 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210421221651-33663a62ff08 h1:qyN5bV+96OX8pL78eXDuz6YlDPzCYgdW74H5yE9BoSU= golang.org/x/sys v0.0.0-20210421221651-33663a62ff08/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 6103965f4480bba8d8f4177470540464a6f7cb04 Mon Sep 17 00:00:00 2001 From: czechbol Date: Tue, 10 Sep 2024 16:52:29 +0200 Subject: [PATCH 13/28] Reduced container image size (#64) * reduced container image size * added upx to builder --- dockerfile | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dockerfile b/dockerfile index 11ae38d..944de29 100644 --- a/dockerfile +++ b/dockerfile @@ -1,4 +1,6 @@ -FROM golang:1.17.7-buster as builder +FROM golang:1.20.3-alpine as builder + +RUN apk add --no-cache bash upx # Set working directory WORKDIR /usr/src/librespeed-cli @@ -9,9 +11,9 @@ COPY . . # Build librespeed-cli RUN ./build.sh -FROM golang:1.17.7-buster +FROM alpine:3.17 # Copy librespeed-cli binary -COPY --from=builder /usr/src/librespeed-cli/out/librespeed-cli* /usr/src/librespeed-cli/librespeed-cli +COPY --from=builder /usr/src/librespeed-cli/out/librespeed-cli* /bin/librespeed-cli -ENTRYPOINT ["/usr/src/librespeed-cli/librespeed-cli"] +CMD ["/bin/librespeed-cli"] From 11183cbf98d1c5ea90b52c3257cd066c63c8c1bb Mon Sep 17 00:00:00 2001 From: Luca Magnabosco Date: Tue, 10 Sep 2024 16:52:45 +0200 Subject: [PATCH 14/28] Add interface option (#65) * speedtest: move source bound Dialer setup to newDialerAddressBound(). * Add "--interface" option. --- README.md | 5 +- defs/options.go | 1 + main.go | 4 ++ speedtest/helper.go | 4 +- speedtest/speedtest.go | 127 +++++++++++++++++++++++--------------- speedtest/util_linux.go | 32 ++++++++++ speedtest/util_windows.go | 10 +++ 7 files changed, 129 insertions(+), 54 deletions(-) create mode 100644 speedtest/util_linux.go create mode 100644 speedtest/util_windows.go diff --git a/README.md b/README.md index c9f7dff..db74ca0 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,10 @@ GLOBAL OPTIONS: --server-json value Use an alternative server list from remote JSON file --local-json value Use an alternative server list from local JSON file, or read from stdin with "--local-json -". - --source SOURCE SOURCE IP address to bind to + --source SOURCE SOURCE IP address to bind to. Incompatible with --interface. + --interface INTERFACE The name of the network interface to bind to. Example: "enp0s3". + Not supported on Windows and incompatible with --source. + Implies --no-icmp. --timeout TIMEOUT HTTP TIMEOUT in seconds. (default: 15) --duration value Upload and download test duration in seconds (default: 15) --chunks value Chunks to download from server, chunk size depends on server configuration (default: 100) diff --git a/defs/options.go b/defs/options.go index 255a5b1..bc7e506 100644 --- a/defs/options.go +++ b/defs/options.go @@ -24,6 +24,7 @@ const ( OptionExclude = "exclude" OptionServerJSON = "server-json" OptionSource = "source" + OptionInterface = "interface" OptionTimeout = "timeout" OptionChunks = "chunks" OptionUploadSize = "upload-size" diff --git a/main.go b/main.go index a60b437..5cb6643 100644 --- a/main.go +++ b/main.go @@ -139,6 +139,10 @@ func main() { Name: defs.OptionSource, Usage: "`SOURCE` IP address to bind to", }, + &cli.StringFlag{ + Name: defs.OptionInterface, + Usage: "network INTERFACE to bind to", + }, &cli.IntFlag{ Name: defs.OptionTimeout, Usage: "HTTP `TIMEOUT` in seconds.", diff --git a/speedtest/helper.go b/speedtest/helper.go index ddc9bc1..4d1d5d7 100644 --- a/speedtest/helper.go +++ b/speedtest/helper.go @@ -28,7 +28,7 @@ const ( ) // doSpeedTest is where the actual speed test happens -func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.TelemetryServer, network string, silent bool) error { +func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.TelemetryServer, network string, silent bool, noICMP bool) error { if serverCount := len(servers); serverCount > 1 { log.Infof("Testing against %d servers", serverCount) } @@ -70,7 +70,7 @@ func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.Tel } // skip ICMP if option given - currentServer.NoICMP = c.Bool(defs.OptionNoICMP) + currentServer.NoICMP = noICMP p, jitter, err := currentServer.ICMPPingAndJitter(pingCount, c.String(defs.OptionSource), network) if err != nil { diff --git a/speedtest/speedtest.go b/speedtest/speedtest.go index 8a68092..93e815f 100644 --- a/speedtest/speedtest.go +++ b/speedtest/speedtest.go @@ -74,6 +74,10 @@ func SpeedTest(c *cli.Context) error { return nil } + if c.String(defs.OptionSource) != "" && c.String(defs.OptionInterface) != "" { + return fmt.Errorf("incompatible options '%s' and '%s'", defs.OptionSource, defs.OptionInterface) + } + // set CSV delimiter gocsv.TagSeparator = c.String(defs.OptionCSVDelimiter) @@ -138,6 +142,8 @@ func SpeedTest(c *cli.Context) error { return errors.New("invalid concurrent requests setting") } + noICMP := c.Bool(defs.OptionNoICMP) + // HTTP requests timeout http.DefaultClient.Timeout = time.Duration(c.Int(defs.OptionTimeout)) * time.Second @@ -157,57 +163,48 @@ func SpeedTest(c *cli.Context) error { transport := http.DefaultTransport.(*http.Transport).Clone() transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: c.Bool(defs.OptionSkipCertVerify)} - // bind to source IP address if given, or if ipv4/ipv6 is forced - if src := c.String(defs.OptionSource); src != "" || (forceIPv4 || forceIPv6) { - var localTCPAddr *net.TCPAddr - if src != "" { - // first we parse the IP to see if it's valid - addr, err := net.ResolveIPAddr(network, src) - if err != nil { - if strings.Contains(err.Error(), "no suitable address") { - if forceIPv6 { - log.Errorf("Address %s is not a valid IPv6 address", src) - } else { - log.Errorf("Address %s is not a valid IPv4 address", src) - } - } else { - log.Errorf("Error parsing source IP: %s", err) - } - return err - } - - log.Debugf("Using %s as source IP", src) - localTCPAddr = &net.TCPAddr{IP: addr.IP} + dialer := &net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + } + // bind to source IP address if given + if src := c.String(defs.OptionSource); src != "" { + var err error + dialer, err = newDialerAddressBound(src, network) + if err != nil { + return err } - - var dialContext func(context.Context, string, string) (net.Conn, error) - defaultDialer := &net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - } - - if localTCPAddr != nil { - defaultDialer.LocalAddr = localTCPAddr - } - - switch { - case forceIPv4: - dialContext = func(ctx context.Context, network, address string) (conn net.Conn, err error) { - return defaultDialer.DialContext(ctx, "tcp4", address) - } - case forceIPv6: - dialContext = func(ctx context.Context, network, address string) (conn net.Conn, err error) { - return defaultDialer.DialContext(ctx, "tcp6", address) - } - default: - dialContext = defaultDialer.DialContext - } - - // set default HTTP client's Transport to the one that binds the source address - // this is modified from http.DefaultTransport - transport.DialContext = dialContext } + // bind to interface if given + if iface := c.String(defs.OptionInterface); iface != "" { + var err error + dialer, err = newDialerInterfaceBound(iface) + if err != nil { + return err + } + // ICMP ping does not support interface binding. + noICMP = true + } + + // enforce if ipv4/ipv6 is forced + var dialContext func(context.Context, string, string) (net.Conn, error) + switch { + case forceIPv4: + dialContext = func(ctx context.Context, network, address string) (conn net.Conn, err error) { + return dialer.DialContext(ctx, "tcp4", address) + } + case forceIPv6: + dialContext = func(ctx context.Context, network, address string) (conn net.Conn, err error) { + return dialer.DialContext(ctx, "tcp6", address) + } + default: + dialContext = dialer.DialContext + } + + // set default HTTP client's Transport to the one that binds the source address + // this is modified from http.DefaultTransport + transport.DialContext = dialContext http.DefaultClient.Transport = transport // load server list @@ -258,7 +255,7 @@ func SpeedTest(c *cli.Context) error { // if --server is given, do speed tests with all of them if len(c.IntSlice(defs.OptionServer)) > 0 { - return doSpeedTest(c, servers, telemetryServer, network, silent) + return doSpeedTest(c, servers, telemetryServer, network, silent, noICMP) } else { // else select the fastest server from the list log.Info("Selecting the fastest server based on ping") @@ -272,7 +269,7 @@ func SpeedTest(c *cli.Context) error { // spawn 10 concurrent pingers for i := 0; i < 10; i++ { - go pingWorker(jobs, results, &wg, c.String(defs.OptionSource), network, c.Bool(defs.OptionNoICMP)) + go pingWorker(jobs, results, &wg, c.String(defs.OptionSource), network, noICMP) } // send ping jobs to workers @@ -309,7 +306,7 @@ func SpeedTest(c *cli.Context) error { } // do speed test on the server - return doSpeedTest(c, []defs.Server{servers[serverIdx]}, telemetryServer, network, silent) + return doSpeedTest(c, []defs.Server{servers[serverIdx]}, telemetryServer, network, silent, noICMP) } } @@ -474,3 +471,31 @@ func contains(arr []int, val int) bool { } return false } + +func newDialerAddressBound(src string, network string) (dialer *net.Dialer, err error) { + // first we parse the IP to see if it's valid + addr, err := net.ResolveIPAddr(network, src) + if err != nil { + if strings.Contains(err.Error(), "no suitable address") { + if network == "ip6" { + log.Errorf("Address %s is not a valid IPv6 address", src) + } else { + log.Errorf("Address %s is not a valid IPv4 address", src) + } + } else { + log.Errorf("Error parsing source IP: %s", err) + } + return nil, err + } + + log.Debugf("Using %s as source IP", src) + localTCPAddr := &net.TCPAddr{IP: addr.IP} + + defaultDialer := &net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + } + + defaultDialer.LocalAddr = localTCPAddr + return defaultDialer, nil +} diff --git a/speedtest/util_linux.go b/speedtest/util_linux.go new file mode 100644 index 0000000..e2a0a64 --- /dev/null +++ b/speedtest/util_linux.go @@ -0,0 +1,32 @@ +package speedtest + +import ( + "net" + "syscall" + "time" + + "golang.org/x/sys/unix" +) + +func newDialerInterfaceBound(iface string) (dialer *net.Dialer, err error) { + // In linux there is the socket option SO_BINDTODEVICE. + // Therefore we can really bind the socket to the device instead of binding to the address that + // would be affected by the default routes. + control := func(network, address string, c syscall.RawConn) error { + var errSock error + err := c.Control((func(fd uintptr) { + errSock = unix.BindToDevice(int(fd), iface) + })) + if err != nil { + return err + } + return errSock + } + + dialer = &net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + Control: control, + } + return dialer, nil +} diff --git a/speedtest/util_windows.go b/speedtest/util_windows.go new file mode 100644 index 0000000..c4a0cd0 --- /dev/null +++ b/speedtest/util_windows.go @@ -0,0 +1,10 @@ +package speedtest + +import ( + "fmt" + "net" +) + +func newDialerInterfaceBound(iface string) (dialer *net.Dialer, err error) { + return nil, fmt.Errorf("cannot bound to interface on Windows") +} From e5c131fe629cd99cd2b352924f18184473368550 Mon Sep 17 00:00:00 2001 From: Salim B Date: Tue, 10 Sep 2024 16:53:16 +0200 Subject: [PATCH 15/28] Fix code-highlighting (#68) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index db74ca0..a0ce7c6 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,7 @@ You can run `librespeed-cli` in a container. You can see the full list of supported options with `librespeed-cli -h`: -```shell script +``` $ librespeed-cli -h NAME: librespeed-cli - Test your Internet speed with LibreSpeed 🚀 From 67adaa29568b337b305d8cab515a8c01ce00fcf4 Mon Sep 17 00:00:00 2001 From: Mkhanyisi Madlavana Date: Tue, 10 Sep 2024 16:53:33 +0200 Subject: [PATCH 16/28] Fix integer overflow issues at high speeds (#73) --- defs/bytes_counter.go | 8 ++++---- defs/server.go | 4 ++-- report/json.go | 4 ++-- speedtest/helper.go | 13 ++++++------- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/defs/bytes_counter.go b/defs/bytes_counter.go index 1553aff..64c155b 100644 --- a/defs/bytes_counter.go +++ b/defs/bytes_counter.go @@ -14,7 +14,7 @@ import ( type BytesCounter struct { start time.Time pos int - total int + total uint64 payload []byte reader io.ReadSeeker mebi bool @@ -33,7 +33,7 @@ func NewCounter() *BytesCounter { func (c *BytesCounter) Write(p []byte) (int, error) { n := len(p) c.lock.Lock() - c.total += n + c.total += uint64(n) c.lock.Unlock() return n, nil @@ -43,7 +43,7 @@ func (c *BytesCounter) Write(p []byte) (int, error) { func (c *BytesCounter) Read(p []byte) (int, error) { n, err := c.reader.Read(p) c.lock.Lock() - c.total += n + c.total += uint64(n) c.pos += n if c.pos == c.uploadSize { c.resetReader() @@ -116,7 +116,7 @@ func (c *BytesCounter) Start() { } // Total returns the total bytes read/written -func (c *BytesCounter) Total() int { +func (c *BytesCounter) Total() uint64 { return c.total } diff --git a/defs/server.go b/defs/server.go index 370b826..ed2ffad 100644 --- a/defs/server.go +++ b/defs/server.go @@ -188,7 +188,7 @@ func (s *Server) PingAndJitter(count int) (float64, float64, error) { } // Download performs the actual download test -func (s *Server) Download(silent bool, useBytes, useMebi bool, requests int, chunks int, duration time.Duration) (float64, int, error) { +func (s *Server) Download(silent bool, useBytes, useMebi bool, requests int, chunks int, duration time.Duration) (float64, uint64, error) { t := time.Now() defer func() { s.TLog.Logf("Download took %s", time.Now().Sub(t).String()) @@ -280,7 +280,7 @@ Loop: } // Upload performs the actual upload test -func (s *Server) Upload(noPrealloc, silent, useBytes, useMebi bool, requests int, uploadSize int, duration time.Duration) (float64, int, error) { +func (s *Server) Upload(noPrealloc, silent, useBytes, useMebi bool, requests int, uploadSize int, duration time.Duration) (float64, uint64, error) { t := time.Now() defer func() { s.TLog.Logf("Upload took %s", time.Now().Sub(t).String()) diff --git a/report/json.go b/report/json.go index fee05b3..d399aed 100644 --- a/report/json.go +++ b/report/json.go @@ -11,8 +11,8 @@ type JSONReport struct { Timestamp time.Time `json:"timestamp"` Server Server `json:"server"` Client Client `json:"client"` - BytesSent int `json:"bytes_sent"` - BytesReceived int `json:"bytes_received"` + BytesSent uint64 `json:"bytes_sent"` + BytesReceived uint64 `json:"bytes_received"` Ping float64 `json:"ping"` Jitter float64 `json:"jitter"` Upload float64 `json:"upload"` diff --git a/speedtest/helper.go b/speedtest/helper.go index 4d1d5d7..1be6203 100644 --- a/speedtest/helper.go +++ b/speedtest/helper.go @@ -15,11 +15,10 @@ import ( "github.com/briandowns/spinner" "github.com/gocarina/gocsv" - log "github.com/sirupsen/logrus" - "github.com/urfave/cli/v2" - "github.com/librespeed/speedtest-cli/defs" "github.com/librespeed/speedtest-cli/report" + log "github.com/sirupsen/logrus" +"github.com/urfave/cli/v2" ) const ( @@ -85,7 +84,7 @@ func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.Tel // get download value var downloadValue float64 - var bytesRead int + var bytesRead uint64 if c.Bool(defs.OptionNoDownload) { log.Info("Download test is disabled") } else { @@ -95,12 +94,12 @@ func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.Tel return err } downloadValue = download - bytesRead = br + bytesRead = uint64(br) } // get upload value var uploadValue float64 - var bytesWritten int + var bytesWritten uint64 if c.Bool(defs.OptionNoUpload) { log.Info("Upload test is disabled") } else { @@ -110,7 +109,7 @@ func doSpeedTest(c *cli.Context, servers []defs.Server, telemetryServer defs.Tel return err } uploadValue = upload - bytesWritten = bw + bytesWritten = uint64(bw) } // print result if --simple is given From b1daf1c451ca40863a7b3dccc70e973683ccc274 Mon Sep 17 00:00:00 2001 From: Mkhanyisi Madlavana Date: Tue, 10 Sep 2024 16:53:48 +0200 Subject: [PATCH 17/28] add `--ca-cert` option (#81) --- README.md | 2 ++ defs/options.go | 1 + main.go | 5 +++++ speedtest/speedtest.go | 22 ++++++++++++++++++++-- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a0ce7c6..f62a89f 100644 --- a/README.md +++ b/README.md @@ -190,6 +190,8 @@ GLOBAL OPTIONS: --upload-size value Size of payload being uploaded in KiB (default: 1024) --secure Use HTTPS instead of HTTP when communicating with LibreSpeed.org operated servers (default: false) + --ca-cert value Use the specified CA certificate PEM bundle file instead + of the system certificate trust store --skip-cert-verify Skip verifying SSL certificate for HTTPS connections (self-signed certs) (default: false) --no-pre-allocate Do not pre allocate upload data. Pre allocation is enabled by default to improve upload performance. To diff --git a/defs/options.go b/defs/options.go index bc7e506..01101be 100644 --- a/defs/options.go +++ b/defs/options.go @@ -30,6 +30,7 @@ const ( OptionUploadSize = "upload-size" OptionDuration = "duration" OptionSecure = "secure" + OptionCACert = "ca-cert" OptionSkipCertVerify = "skip-cert-verify" OptionNoPreAllocate = "no-pre-allocate" OptionVersion = "version" diff --git a/main.go b/main.go index 5cb6643..0213293 100644 --- a/main.go +++ b/main.go @@ -168,6 +168,11 @@ func main() { Usage: "Use HTTPS instead of HTTP when communicating with\n" + "\tLibreSpeed.org operated servers", }, + &cli.StringFlag{ + Name: defs.OptionCACert, + Usage: "Use the specified CA certificate PEM bundle file instead\n" + + "\tof the system certificate trust store", + }, &cli.BoolFlag{ Name: defs.OptionSkipCertVerify, Usage: "Skip verifying SSL certificate for HTTPS connections (self-signed certs)", diff --git a/speedtest/speedtest.go b/speedtest/speedtest.go index 93e815f..d461996 100644 --- a/speedtest/speedtest.go +++ b/speedtest/speedtest.go @@ -3,6 +3,7 @@ package speedtest import ( "context" "crypto/tls" + "crypto/x509" "encoding/json" "errors" "fmt" @@ -160,8 +161,25 @@ func SpeedTest(c *cli.Context) error { network = "ip" } - transport := http.DefaultTransport.(*http.Transport).Clone() - transport.TLSClientConfig = &tls.Config{InsecureSkipVerify: c.Bool(defs.OptionSkipCertVerify)} + transport := http.DefaultTransport.(*http.Transport).Clone() + + if caCertFileName := c.String(defs.OptionCACert); caCertFileName != "" { + caCert, err := ioutil.ReadFile(caCertFileName) + if err != nil { + log.Fatal(err) + } + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) + + transport.TLSClientConfig = &tls.Config{ + InsecureSkipVerify: c.Bool(defs.OptionSkipCertVerify), + RootCAs: caCertPool, + } + } else { + transport.TLSClientConfig = &tls.Config{ + InsecureSkipVerify: c.Bool(defs.OptionSkipCertVerify), + } + } dialer := &net.Dialer{ Timeout: 30 * time.Second, From 058cd387c14c42178724e17da7804845f955c38b Mon Sep 17 00:00:00 2001 From: Maddie Zhan Date: Tue, 10 Sep 2024 23:06:31 +0800 Subject: [PATCH 18/28] Update goreleaser config to v2 --- .goreleaser.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 44b08eb..c2f0e63 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,3 +1,4 @@ +version: 2 project_name: "librespeed-cli" #dist: ./out before: @@ -73,11 +74,10 @@ archives: format: zip files: - LICENSE - rlcp: true checksum: name_template: "checksums.txt" changelog: - skip: false + disable: false sort: asc release: github: From d23c1b7b727657cc818f8cf596802d4f651ba00b Mon Sep 17 00:00:00 2001 From: Maddie Zhan Date: Tue, 10 Sep 2024 23:09:08 +0800 Subject: [PATCH 19/28] go mod tidy to fix build --- go.mod | 4 +--- go.sum | 43 +++---------------------------------------- 2 files changed, 4 insertions(+), 43 deletions(-) diff --git a/go.mod b/go.mod index fb1f268..06659e4 100644 --- a/go.mod +++ b/go.mod @@ -9,10 +9,8 @@ require ( github.com/gocarina/gocsv v0.0.0-20230406101422-6445c2b15027 github.com/google/uuid v1.3.0 // indirect github.com/mattn/go-isatty v0.0.18 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/sirupsen/logrus v1.9.0 github.com/urfave/cli/v2 v2.25.1 golang.org/x/net v0.9.0 // indirect - gopkg.in/yaml.v2 v2.2.3 // indirect + golang.org/x/sys v0.7.0 ) diff --git a/go.sum b/go.sum index d8b8382..1ce4b62 100644 --- a/go.sum +++ b/go.sum @@ -1,79 +1,50 @@ -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/briandowns/spinner v1.12.0 h1:72O0PzqGJb6G3KgrcIOtL/JAGGZ5ptOMCn9cUHmqsmw= -github.com/briandowns/spinner v1.12.0/go.mod h1:QOuQk7x+EaDASo80FEXwlwiA+j/PPIcX3FScO+3/ZPQ= github.com/briandowns/spinner v1.23.0 h1:alDF2guRWqa/FOZZYWjlMIx2L6H0wyewPxo/CH4Pt2A= github.com/briandowns/spinner v1.23.0/go.mod h1:rPG4gmXeN3wQV/TsAY4w8lPdIM6RX3yqeBQJSrbXjuE= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= -github.com/go-ping/ping v0.0.0-20210407214646-e4e642a95741 h1:b0sLP++Tsle+s57tqg5sUk1/OQsC6yMCciVeqNzOcwU= -github.com/go-ping/ping v0.0.0-20210407214646-e4e642a95741/go.mod h1:35JbSyV/BYqHwwRA6Zr1uVDm1637YlNOU61wI797NPI= github.com/go-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw= github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk= -github.com/gocarina/gocsv v0.0.0-20210408192840-02d7211d929d h1:r3mStZSyjKhEcgbJ5xtv7kT5PZw/tDiFBTMgQx2qsXE= -github.com/gocarina/gocsv v0.0.0-20210408192840-02d7211d929d/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI= github.com/gocarina/gocsv v0.0.0-20230406101422-6445c2b15027 h1:LCGzZb4kMUUjMUzLxxqSJBwo9szUO0tK8cOxnEOT4Jc= github.com/gocarina/gocsv v0.0.0-20230406101422-6445c2b15027/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= -github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/urfave/cli/v2 v2.25.1 h1:zw8dSP7ghX0Gmm8vugrs6q9Ku0wzweqPyshy+syu9Gw= github.com/urfave/cli/v2 v2.25.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758 h1:aEpZnXcAmXkd6AvLb2OPt+EN1Zu/8Ne3pCqPjja5PXY= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= @@ -85,16 +56,8 @@ golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210421221651-33663a62ff08 h1:qyN5bV+96OX8pL78eXDuz6YlDPzCYgdW74H5yE9BoSU= -golang.org/x/sys v0.0.0-20210421221651-33663a62ff08/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -112,7 +75,6 @@ golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= @@ -121,7 +83,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From d33e431b58774807f608f7a38bd5e5fd9cc3dfc4 Mon Sep 17 00:00:00 2001 From: Maddie Zhan Date: Tue, 10 Sep 2024 23:22:34 +0800 Subject: [PATCH 20/28] fix build for non-windows/linux platforms --- speedtest/{util_windows.go => util.go} | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) rename speedtest/{util_windows.go => util.go} (53%) diff --git a/speedtest/util_windows.go b/speedtest/util.go similarity index 53% rename from speedtest/util_windows.go rename to speedtest/util.go index c4a0cd0..ce04c00 100644 --- a/speedtest/util_windows.go +++ b/speedtest/util.go @@ -1,3 +1,6 @@ +//go:build !linux +// +build !linux + package speedtest import ( @@ -6,5 +9,5 @@ import ( ) func newDialerInterfaceBound(iface string) (dialer *net.Dialer, err error) { - return nil, fmt.Errorf("cannot bound to interface on Windows") + return nil, fmt.Errorf("cannot bound to interface on this platform") } From 7573b65ebc89a4cf463334dbdfab5b3edc706149 Mon Sep 17 00:00:00 2001 From: Maddie Zhan Date: Wed, 11 Sep 2024 17:17:37 +0800 Subject: [PATCH 21/28] Upgrade to Go 1.18 as minimum required version With dependency upgrade. Fixes issue #90 --- go.mod | 29 +++++++++++++++++--------- go.sum | 64 +++++++++++++++++++++++++--------------------------------- 2 files changed, 46 insertions(+), 47 deletions(-) diff --git a/go.mod b/go.mod index 06659e4..b5a75f0 100644 --- a/go.mod +++ b/go.mod @@ -1,16 +1,25 @@ module github.com/librespeed/speedtest-cli -go 1.14 +go 1.18 require ( - github.com/briandowns/spinner v1.23.0 - github.com/fatih/color v1.15.0 // indirect + github.com/briandowns/spinner v1.23.1 github.com/go-ping/ping v1.1.0 - github.com/gocarina/gocsv v0.0.0-20230406101422-6445c2b15027 - github.com/google/uuid v1.3.0 // indirect - github.com/mattn/go-isatty v0.0.18 // indirect - github.com/sirupsen/logrus v1.9.0 - github.com/urfave/cli/v2 v2.25.1 - golang.org/x/net v0.9.0 // indirect - golang.org/x/sys v0.7.0 + github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1 + github.com/sirupsen/logrus v1.9.3 + github.com/urfave/cli/v2 v2.27.4 + golang.org/x/sys v0.25.0 +) + +require ( + github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect + github.com/fatih/color v1.17.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/term v0.24.0 // indirect ) diff --git a/go.sum b/go.sum index 1ce4b62..83f949f 100644 --- a/go.sum +++ b/go.sum @@ -1,90 +1,80 @@ -github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/briandowns/spinner v1.23.0 h1:alDF2guRWqa/FOZZYWjlMIx2L6H0wyewPxo/CH4Pt2A= github.com/briandowns/spinner v1.23.0/go.mod h1:rPG4gmXeN3wQV/TsAY4w8lPdIM6RX3yqeBQJSrbXjuE= +github.com/briandowns/spinner v1.23.1 h1:t5fDPmScwUjozhDj4FA46p5acZWIPXYE30qW2Ptu650= +github.com/briandowns/spinner v1.23.1/go.mod h1:LaZeM4wm2Ywy6vO571mvhQNRcWfRUnXOs0RcKV0wYKM= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/go-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw= github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk= github.com/gocarina/gocsv v0.0.0-20230406101422-6445c2b15027 h1:LCGzZb4kMUUjMUzLxxqSJBwo9szUO0tK8cOxnEOT4Jc= github.com/gocarina/gocsv v0.0.0-20230406101422-6445c2b15027/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI= +github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1 h1:FWNFq4fM1wPfcK40yHE5UO3RUdSNPaBC+j3PokzA6OQ= +github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/urfave/cli/v2 v2.25.1 h1:zw8dSP7ghX0Gmm8vugrs6q9Ku0wzweqPyshy+syu9Gw= github.com/urfave/cli/v2 v2.25.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= +github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8= +github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 63c75be0fc1191b4cebd2886526780f914ac1470 Mon Sep 17 00:00:00 2001 From: Anton Kudriavtsev Date: Thu, 12 Jun 2025 12:28:34 +0300 Subject: [PATCH 22/28] Fix telemetry parsing error log (#91) --- speedtest/speedtest.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/speedtest/speedtest.go b/speedtest/speedtest.go index d461996..1cdda3f 100644 --- a/speedtest/speedtest.go +++ b/speedtest/speedtest.go @@ -105,7 +105,7 @@ func SpeedTest(c *cli.Context) error { return err } if err := json.Unmarshal(b, &telemetryServer); err != nil { - log.Errorf("Error parsing %s: %s", err) + log.Errorf("Error parsing %s: %s", telemetryJSON, err) return err } } From 78c9095ca9062bb8387031b2a22fb161ef99a9d3 Mon Sep 17 00:00:00 2001 From: An Date: Thu, 12 Jun 2025 17:29:06 +0800 Subject: [PATCH 23/28] add fwmark (#92) --- defs/options.go | 1 + main.go | 7 ++++++- speedtest/speedtest.go | 42 ++++++++++++++++++++++------------------- speedtest/util_linux.go | 10 ++++++++-- 4 files changed, 38 insertions(+), 22 deletions(-) diff --git a/defs/options.go b/defs/options.go index 01101be..84662b5 100644 --- a/defs/options.go +++ b/defs/options.go @@ -42,4 +42,5 @@ const ( OptionTelemetryPath = "telemetry-path" OptionTelemetryShare = "telemetry-share" OptionTelemetryExtra = "telemetry-extra" + OptionFwmark = "fwmark" ) diff --git a/main.go b/main.go index 0213293..cc948cc 100644 --- a/main.go +++ b/main.go @@ -171,7 +171,7 @@ func main() { &cli.StringFlag{ Name: defs.OptionCACert, Usage: "Use the specified CA certificate PEM bundle file instead\n" + - "\tof the system certificate trust store", + "\tof the system certificate trust store", }, &cli.BoolFlag{ Name: defs.OptionSkipCertVerify, @@ -218,6 +218,11 @@ func main() { Usage: "Send a custom message along with the telemetry results.\n" + "\tImplies --" + defs.OptionShare, }, + &cli.IntFlag{ + Name: defs.OptionFwmark, + Usage: "firewall mark to set on socket.", + Value: 0, + }, }, } diff --git a/speedtest/speedtest.go b/speedtest/speedtest.go index 1cdda3f..20018ac 100644 --- a/speedtest/speedtest.go +++ b/speedtest/speedtest.go @@ -161,25 +161,25 @@ func SpeedTest(c *cli.Context) error { network = "ip" } - transport := http.DefaultTransport.(*http.Transport).Clone() + transport := http.DefaultTransport.(*http.Transport).Clone() - if caCertFileName := c.String(defs.OptionCACert); caCertFileName != "" { - caCert, err := ioutil.ReadFile(caCertFileName) - if err != nil { - log.Fatal(err) - } - caCertPool := x509.NewCertPool() - caCertPool.AppendCertsFromPEM(caCert) + if caCertFileName := c.String(defs.OptionCACert); caCertFileName != "" { + caCert, err := ioutil.ReadFile(caCertFileName) + if err != nil { + log.Fatal(err) + } + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM(caCert) - transport.TLSClientConfig = &tls.Config{ - InsecureSkipVerify: c.Bool(defs.OptionSkipCertVerify), - RootCAs: caCertPool, - } - } else { - transport.TLSClientConfig = &tls.Config{ - InsecureSkipVerify: c.Bool(defs.OptionSkipCertVerify), - } - } + transport.TLSClientConfig = &tls.Config{ + InsecureSkipVerify: c.Bool(defs.OptionSkipCertVerify), + RootCAs: caCertPool, + } + } else { + transport.TLSClientConfig = &tls.Config{ + InsecureSkipVerify: c.Bool(defs.OptionSkipCertVerify), + } + } dialer := &net.Dialer{ Timeout: 30 * time.Second, @@ -195,9 +195,13 @@ func SpeedTest(c *cli.Context) error { } // bind to interface if given - if iface := c.String(defs.OptionInterface); iface != "" { + // bind to interface if given + iface := c.String(defs.OptionInterface) + fwmark := c.Int(defs.OptionFwmark) + + if iface != "" || fwmark > 0 { var err error - dialer, err = newDialerInterfaceBound(iface) + dialer, err = newDialerInterfaceOrFwmarkBound(iface, fwmark) if err != nil { return err } diff --git a/speedtest/util_linux.go b/speedtest/util_linux.go index e2a0a64..e153e87 100644 --- a/speedtest/util_linux.go +++ b/speedtest/util_linux.go @@ -8,14 +8,20 @@ import ( "golang.org/x/sys/unix" ) -func newDialerInterfaceBound(iface string) (dialer *net.Dialer, err error) { +func newDialerInterfaceOrFwmarkBound(iface string, fwmark int) (dialer *net.Dialer, err error) { // In linux there is the socket option SO_BINDTODEVICE. // Therefore we can really bind the socket to the device instead of binding to the address that // would be affected by the default routes. control := func(network, address string, c syscall.RawConn) error { var errSock error err := c.Control((func(fd uintptr) { - errSock = unix.BindToDevice(int(fd), iface) + if iface != "" { + errSock = unix.BindToDevice(int(fd), iface) + } + + if fwmark > 0 { + errSock = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK, fwmark) + } })) if err != nil { return err From c9decb3fda109b0aed3bd9692ea6dec7b7a20297 Mon Sep 17 00:00:00 2001 From: Meng Zhuo Date: Thu, 12 Jun 2025 17:30:36 +0800 Subject: [PATCH 24/28] Enable riscv64 release (#95) --- .goreleaser.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.goreleaser.yml b/.goreleaser.yml index c2f0e63..4fabfbe 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -54,6 +54,7 @@ builds: - mipsle - mips64 - mips64le + - riscv64 gomips: - hardfloat - softfloat From 0c565b724b05c3e38bb270b6cd6bab1309989fd3 Mon Sep 17 00:00:00 2001 From: Vivek Kumar <167422483+Vivekkumar-IN@users.noreply.github.com> Date: Thu, 12 Jun 2025 15:00:49 +0530 Subject: [PATCH 25/28] Update Go version requirement to 1.18+ in README (#101) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f62a89f..d3945cf 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ This is a command line interface for LibreSpeed speed test backends, written in [![asciicast](https://asciinema.org/a/J17bUAilWI3qR12JyhfGvPwu2.svg)](https://asciinema.org/a/J17bUAilWI3qR12JyhfGvPwu2) ## Requirements for compiling -- Go 1.14+ +- Go 1.18+ ## Runtime requirements - Any [Go supported platforms](https://github.com/golang/go/wiki/MinimumRequirements) From 7ed6fe234c247d13ba7dd0cb323c9926d8ee8b55 Mon Sep 17 00:00:00 2001 From: Maddie Zhan Date: Thu, 12 Jun 2025 17:33:06 +0800 Subject: [PATCH 26/28] fix: goreleaser archives.format_overrides.format deprecation --- .goreleaser.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.goreleaser.yml b/.goreleaser.yml index 4fabfbe..a0ee28a 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -72,7 +72,7 @@ builds: archives: - format_overrides: - goos: windows - format: zip + formats: ['zip'] files: - LICENSE checksum: From 95f2c8207ae62acd6806e4cc6dbe3ea588a55640 Mon Sep 17 00:00:00 2001 From: Maddie Zhan Date: Thu, 12 Jun 2025 17:36:59 +0800 Subject: [PATCH 27/28] fix: fix build for non-linux platform --- speedtest/util.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/speedtest/util.go b/speedtest/util.go index ce04c00..0a35393 100644 --- a/speedtest/util.go +++ b/speedtest/util.go @@ -8,6 +8,6 @@ import ( "net" ) -func newDialerInterfaceBound(iface string) (dialer *net.Dialer, err error) { +func newDialerInterfaceOrFwmarkBound(iface string, fwmark int) (dialer *net.Dialer, err error) { return nil, fmt.Errorf("cannot bound to interface on this platform") } From 14717ac78b0125d17e7c8d450215d3f271cb7ef3 Mon Sep 17 00:00:00 2001 From: Maddie Zhan Date: Thu, 12 Jun 2025 17:39:18 +0800 Subject: [PATCH 28/28] chore: update github.com/go-ping/ping dependency update due to CVE in indirect dependency golang.org/x/net --- go.mod | 14 ++++++++------ go.sum | 46 +++++++++++----------------------------------- 2 files changed, 19 insertions(+), 41 deletions(-) diff --git a/go.mod b/go.mod index b5a75f0..da5d4ff 100644 --- a/go.mod +++ b/go.mod @@ -1,14 +1,16 @@ module github.com/librespeed/speedtest-cli -go 1.18 +go 1.23.0 + +toolchain go1.24.2 require ( github.com/briandowns/spinner v1.23.1 - github.com/go-ping/ping v1.1.0 + github.com/go-ping/ping v1.2.0 github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1 github.com/sirupsen/logrus v1.9.3 github.com/urfave/cli/v2 v2.27.4 - golang.org/x/sys v0.25.0 + golang.org/x/sys v0.33.0 ) require ( @@ -19,7 +21,7 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect - golang.org/x/net v0.29.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/term v0.24.0 // indirect + golang.org/x/net v0.41.0 // indirect + golang.org/x/sync v0.15.0 // indirect + golang.org/x/term v0.32.0 // indirect ) diff --git a/go.sum b/go.sum index 83f949f..51dbae2 100644 --- a/go.sum +++ b/go.sum @@ -1,80 +1,56 @@ -github.com/briandowns/spinner v1.23.0 h1:alDF2guRWqa/FOZZYWjlMIx2L6H0wyewPxo/CH4Pt2A= -github.com/briandowns/spinner v1.23.0/go.mod h1:rPG4gmXeN3wQV/TsAY4w8lPdIM6RX3yqeBQJSrbXjuE= github.com/briandowns/spinner v1.23.1 h1:t5fDPmScwUjozhDj4FA46p5acZWIPXYE30qW2Ptu650= github.com/briandowns/spinner v1.23.1/go.mod h1:LaZeM4wm2Ywy6vO571mvhQNRcWfRUnXOs0RcKV0wYKM= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= -github.com/go-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw= -github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk= -github.com/gocarina/gocsv v0.0.0-20230406101422-6445c2b15027 h1:LCGzZb4kMUUjMUzLxxqSJBwo9szUO0tK8cOxnEOT4Jc= -github.com/gocarina/gocsv v0.0.0-20230406101422-6445c2b15027/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI= +github.com/go-ping/ping v1.2.0 h1:vsJ8slZBZAXNCK4dPcI2PEE9eM9n9RbXbGouVQ/Y4yQ= +github.com/go-ping/ping v1.2.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk= github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1 h1:FWNFq4fM1wPfcK40yHE5UO3RUdSNPaBC+j3PokzA6OQ= github.com/gocarina/gocsv v0.0.0-20240520201108-78e41c74b4b1/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98= -github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/urfave/cli/v2 v2.25.1 h1:zw8dSP7ghX0Gmm8vugrs6q9Ku0wzweqPyshy+syu9Gw= -github.com/urfave/cli/v2 v2.25.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8= github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= -golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= -golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= +golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= +golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= -golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= -golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= -golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= -golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= +golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=