speedtest-rs

a tool like speedtest-cli, but in Rust and lacking a few things (for now)!

Project Status: Wip - Initial development is in progress, but there has not yet been a stable, usable release suitable for the public. Build Status

This is working at the moment. Download and upload testing is done. There is some separation of concerns between the GUI and the backend so this might be reusable in other crates.

Purpose

This is a learning exercise for me to learn:

Plans may include a runtime-free tool (with musl especially) that can run against speedtest.net. Cross-compile this and maybe it can go anywhere! I also hope that this is less demanding on resources than the Python or Go versions.

This is currently based heavily on the popular Python implementation:

https://github.com/sivel/speedtest-cli

For now, it would only support speedtest.net and not Speedtest Mini.

There is also a Go version which is different from the other CLI speedtest clients I've found:

https://github.com/traetox/speedtest

It seems different as it appears to just use TCP connections and some protocol. It's probably more suitable to high-speed connections. I'll probably offer it as an alternative option that is also built-in.

How this speedtest works like speedtest-cli and a bit about speedtest.net in general and about speedtest-go

  1. "http://www.speedtest.net/speedtest-config.php" is downloaded.
  2. The client attributes are read.

    In the original Python implementation, times, download, and upload elements' attributes are also read.

Deleting these unused elements (times, download, and upload) still lets the Python implementation work. As far as I know, they are unused. Judging from the history of the original Python implementation, they were introduced in the first commit but never removed and stayed in as further refactoring was done.

  1. The server list is downloaded. http://www.speedtest.net/speedtest-servers-static.php
  2. Each server attributes are read.
  3. The five closest servers are found by the latitude and longitude with the original client attribute from the configuration.
  4. These five servers are tested for latency and the best server is selected.
  5. Download and time GETs for [350, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000] with random(size)x(size).jpg, like /random350x350.jpg from the fastest server.
  6. The Download speed is calculated from the sum of all the files and the time to took to download 6 files at a time in parallel from the list.
  7. Upload and time POSTs for [250000(25 times), 500000(25 times)] where bytes of a rolling 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ cycled to the desired size is posted as a request with that data. This is timed. It is posted that url that is in the server configuration.
  8. Same calculation as download but ... for upload!?! :scream:
  9. There's some sharing stuff but that hasn't been investigated yet. It it probably pretty simply.

Note that some of these operations are different on one particular Go version of the speedtest. In that version, tests are done to find an amount of data that can run for a default of 3 seconds. In particular, speedtest-cli tests with what Ookla calls the "HTTP Legacy Fallback" for hosts that cannot establish a direct TCP connection.