From 79afc769eac1bddccfb412b0b084805e4b586692 Mon Sep 17 00:00:00 2001 From: Les W <30345058+leswaters@users.noreply.github.com> Date: Sat, 9 Jul 2022 16:13:26 +0100 Subject: [PATCH 01/25] Update README.md Added simple manual instructions --- README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8df4371..7608d78 100755 --- a/README.md +++ b/README.md @@ -32,7 +32,20 @@ Works with mobile versions too. * MySQL database to store test results (optional, PostgreSQL and SQLite also supported) * A fast! internet connection -## Installation videos +## Installation +Assuming you have PHP installed, the installation steps are quite simple. +I set this up on a QNAP. +For this example, I am using a folder called **speedtest** in my web share area. + +1. Choose one of the example-xxx.html files as your new index.html in your speedtest folder. I used: example-singleServer-full.html +2. Add: speedtest.js, speedtest_worker.js, and favicon.ico to your speedtest folder. +3. Download all of the backend folder into speedtest/backend. +4. Download all of the results folder into speedtest/results. +5. Be sure your permissions allow execute (755). +6. Visit YOURSITE/speedtest/index.html and voila! + +### Installation Video +There is a more in-depth installation video here: * [Quick start installation guide for Ubuntu Server 19.04](https://fdossena.com/?p=speedtest/quickstart_v5_ubuntu.frag) ## Android app From d1ca8c2630b56a5ed0ecd1072077d43e71f471c2 Mon Sep 17 00:00:00 2001 From: bt90 Date: Thu, 14 Jul 2022 16:45:28 +0200 Subject: [PATCH 02/25] Link to docker documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8df4371..491e346 100755 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Works with mobile versions too. A template to build an Android client for your LibreSpeed installation is available [here](https://github.com/librespeed/speedtest-android). ## Docker -A docker image is available on the [Docker Hub](https://registry.hub.docker.com/r/adolfintel/speedtest), see `doc_docker.md` for more info about it +A docker image is available on the [Docker Hub](https://registry.hub.docker.com/r/adolfintel/speedtest), check our [docker documentation](doc_docker.md) for more info about it ## Go backend A Go implementation is available in the [`speedtest-go`](https://github.com/librespeed/speedtest-go) repo, maintained by [Maddie Zhan](https://github.com/maddie). From 16e0fb9bf4c275262d74b49c453c6ce50e6f5ae3 Mon Sep 17 00:00:00 2001 From: bt90 Date: Thu, 14 Jul 2022 17:08:12 +0200 Subject: [PATCH 03/25] Add basic docker compose example --- doc_docker.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/doc_docker.md b/doc_docker.md index 753fe02..a8cd69a 100755 --- a/doc_docker.md +++ b/doc_docker.md @@ -9,6 +9,34 @@ docker pull adolfintel/speedtest You will now have a new docker image called `adolfintel/speedtest`. + +## Docker Compose +To start the container using [docker compose](https://docs.docker.com/compose/) the following configuration can be used: + +```yml +version: '3.7' +services: + speedtest: + container_name: speedtest + image: adolfintel/speedtest + restart: always + environment: + MODE: standalone + #TITLE: "LibreSpeed" + #TELEMETRY: "false" + #ENABLE_ID_OBFUSCATION: "false" + #REDACT_IP_ADDRESSES: "false" + #PASSWORD: + #EMAIL: + #DISABLE_IPINFO: "false" + #DISTANCE: "km" + #WEBPORT: 80 + ports: + - "80:80" # webport mapping (host:container) +``` + +Please adjust the environment variables according to the intended operating mode. + ## Standalone mode If you want to install LibreSpeed on a single server, you need to configure it in standalone mode. To do this, set the `MODE` environment variable to `standalone`. From dd8c5f74f6b7acc0414ad22e2b8ad6e924b04bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?An=20=7C=20Anton=20R=C3=B6hm?= <18481195+AnTheMaker@users.noreply.github.com> Date: Sat, 1 Oct 2022 13:45:28 +0200 Subject: [PATCH 04/25] add descriptive alt-text to GIF --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8df4371..b5671fa 100755 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Works with mobile versions too. * Results sharing (optional) * Multiple Points of Test (optional) -![Screenshot](https://speedtest.fdossena.com/mpot_v6.gif) +![Screenrecording of a running Speedtest](https://speedtest.fdossena.com/mpot_v6.gif) ## Server requirements From 71e3b4713012ae32e1a026727d597f8d9fabb87a Mon Sep 17 00:00:00 2001 From: 0kyn <0kyn.dev@gmail.com> Date: Mon, 3 Oct 2022 21:16:26 +0200 Subject: [PATCH 05/25] Fix some typos and formatting --- Dockerfile | 6 +----- doc.md | 10 +++++----- speedtest.js | 2 +- speedtest_worker.js | 8 ++++---- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/Dockerfile b/Dockerfile index c510c98..5c5219f 100755 --- a/Dockerfile +++ b/Dockerfile @@ -12,11 +12,9 @@ RUN apt-get update && apt-get install -y \ && docker-php-ext-install -j$(nproc) gd pdo pdo_mysql pdo_pgsql pgsql # Prepare files and folders - RUN mkdir -p /speedtest/ # Copy sources - COPY backend/ /speedtest/backend COPY results/*.php /speedtest/results/ @@ -30,8 +28,7 @@ COPY docker/servers.json /servers.json COPY docker/*.php /speedtest/ COPY docker/entrypoint.sh / -# Prepare environment variabiles defaults - +# Prepare default environment variables ENV TITLE=LibreSpeed ENV MODE=standalone ENV PASSWORD=password @@ -41,6 +38,5 @@ ENV REDACT_IP_ADDRESSES=false ENV WEBPORT=80 # Final touches - EXPOSE 80 CMD ["bash", "/entrypoint.sh"] diff --git a/doc.md b/doc.md index 620b30e..787cded 100755 --- a/doc.md +++ b/doc.md @@ -117,7 +117,7 @@ If you're not using telemetry and results sharing, you can delete the `results` Details about the examples and how to make custom UIs will be discussed later. If you don't want to make a custom UI, feel free to modify the example and replace "LibreSpeed Example" with the name of your test. #### Privacy -Telemetry contains personal information (according to GDPR defintion), therefore it is important to treat this data respectfully of national and international laws, especially if you plan to offer the service in the European Union. +Telemetry contains personal information (according to GDPR definition), therefore it is important to treat this data respectfully of national and international laws, especially if you plan to offer the service in the European Union. `example-singleServer-full.html` and `example-multipleServers-full.html` both contain a privacy policy for the service: you MUST read it, change it if necessary, and add your email address for data deletion requests. __Failure to comply with GDPR regulations can get you in serious trouble.__ @@ -506,7 +506,7 @@ You can think of this as a finite state machine. These are the states (use getSt ``` While in state 1, you can only add test points, you cannot change the test settings. When you're done, use selectServer(callback) to select the test point with the lowest ping. This is asynchronous, when it's done, it will call your callback function and move to state 2. Calling setSelectedServer(server) will manually select a server and move to state 2. * __2__: test point selected, ready to start the test. Use `start()` to begin, this will move to state 3 -* __3__: test running. Here, your `onupdate` event calback will be called periodically, with data coming from the worker about speed and progress. A data object will be passed to your `onupdate` function, with the following items: +* __3__: test running. Here, your `onupdate` event callback will be called periodically, with data coming from the worker about speed and progress. A data object will be passed to your `onupdate` function, with the following items: - `dlStatus`: download speed in mbps - `ulStatus`: upload speed in mbps - `pingStatus`: ping in ms @@ -664,7 +664,7 @@ Access-Control-Allow-Headers: Content-Encoding, Content-Type This file stores telemetry information into the database. Data is passed as POST parameters: -* `ispinfo`: ISP info (if enabled, empty strng otherwise) +* `ispinfo`: ISP info (if enabled, empty string otherwise) * `extra`: the `telemetry_extra` string passed to the worker (if set, empty string otherwise) * `dl`: download speed * `ul`: upload speed @@ -741,7 +741,7 @@ s.setParameter("url_ping","backend/empty.dat"); s.setParameter("test_order","P_D_U"); ``` -This will point to our static files and set the test to only do ping/jitter, download and uplod tests. +This will point to our static files and set the test to only do ping/jitter, download and upload tests. ## Troubleshooting These are the most common issues reported by users, and how to fix them. If you still need help, contact me at [info@fdossena.com](mailto:info@fdossena.com). @@ -807,7 +807,7 @@ Also, make sure that the web server has write permission on the `results` folder ## Known bugs and limitations ### General -* The ping/jitter test is measured by seeing how long it takes for an empty XHR to complete. It is not an acutal ICMP ping. Different browsers may also show different results, especially on very fast connections on slow devices. +* The ping/jitter test is measured by seeing how long it takes for an empty XHR to complete. It is not an actual ICMP ping. Different browsers may also show different results, especially on very fast connections on slow devices. ### IE specific * The upload test is not precise on very fast connections with high latency (will probably be fixed by Edge 17) * On IE11, a same origin policy error is erroneously triggered under unknown conditions. Seems to be related to running the test from unusual URLs like a top level domain (for instance http://abc/speedtest). These are bugs in IE11's implementation of the same origin policy, not in the speedtest itself. diff --git a/speedtest.js b/speedtest.js index a2fdb68..f614a53 100755 --- a/speedtest.js +++ b/speedtest.js @@ -27,7 +27,7 @@ } While in state 1, you can only add test points, you cannot change the test settings. When you're done, use selectServer(callback) to select the test point with the lowest ping. This is asynchronous, when it's done, it will call your callback function and move to state 2. Calling setSelectedServer(server) will manually select a server and move to state 2. - 2: test point selected, ready to start the test. Use start() to begin, this will move to state 3 - - 3: test running. Here, your onupdate event calback will be called periodically, with data coming from the worker about speed and progress. A data object will be passed to your onupdate function, with the following items: + - 3: test running. Here, your onupdate event callback will be called periodically, with data coming from the worker about speed and progress. A data object will be passed to your onupdate function, with the following items: - dlStatus: download speed in mbps - ulStatus: upload speed in mbps - pingStatus: ping in ms diff --git a/speedtest_worker.js b/speedtest_worker.js index 2899e70..a01b4ac 100755 --- a/speedtest_worker.js +++ b/speedtest_worker.js @@ -60,12 +60,12 @@ var settings = { garbagePhp_chunkSize: 100, // size of chunks sent by garbage.php (can be different if enable_quirks is active) enable_quirks: true, // enable quirks for specific browsers. currently it overrides settings to optimize for specific browsers, unless they are already being overridden with the start command ping_allowPerformanceApi: true, // if enabled, the ping test will attempt to calculate the ping more precisely using the Performance API. Currently works perfectly in Chrome, badly in Edge, and not at all in Firefox. If Performance API is not supported or the result is obviously wrong, a fallback is provided. - overheadCompensationFactor: 1.06, //can be changed to compensatie for transport overhead. (see doc.md for some other values) + overheadCompensationFactor: 1.06, //can be changed to compensate for transport overhead. (see doc.md for some other values) useMebibits: false, //if set to true, speed will be reported in mebibits/s instead of megabits/s telemetry_level: 0, // 0=disabled, 1=basic (results only), 2=full (results and timing) 3=debug (results+log) url_telemetry: "results/telemetry.php", // path to the script that adds telemetry data to the database telemetry_extra: "", //extra data that can be passed to the telemetry through the settings - forceIE11Workaround: false //when set to true, it will foce the IE11 upload test on all browsers. Debug only + forceIE11Workaround: false //when set to true, it will force the IE11 upload test on all browsers. Debug only }; var xhr = null; // array of currently active xhr requests @@ -423,7 +423,7 @@ function dlTest(done) { 200 ); } -// upload test, calls done function whent it's over +// upload test, calls done function when it's over var ulCalled = false; // used to prevent multiple accidental calls to ulTest function ulTest(done) { tverb("ulTest"); @@ -474,7 +474,7 @@ function ulTest(done) { } } if (ie11workaround) { - // IE11 workarond: xhr.upload does not work properly, therefore we send a bunch of small 256k requests and use the onload event as progress. This is not precise, especially on fast connections + // IE11 workaround: xhr.upload does not work properly, therefore we send a bunch of small 256k requests and use the onload event as progress. This is not precise, especially on fast connections xhr[i].onload = xhr[i].onerror = function() { tverb("ul stream progress event (ie11wa)"); totLoaded += reqsmall.size; From 427edfc416596464e9c6fc64cb56b5c40c40790b Mon Sep 17 00:00:00 2001 From: Marc Zampetti Date: Wed, 9 Aug 2023 16:36:48 -0400 Subject: [PATCH 06/25] Updated Docker to use php8.2-apache as the upstream image. --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index c510c98..ae32f5a 100755 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM php:7.4-apache +FROM php:8.2-apache # Install extensions RUN apt-get update && apt-get install -y \ From abc85eb8c53f62b2c80a3d4551b9b463d0984433 Mon Sep 17 00:00:00 2001 From: Peter Dave Hello Date: Tue, 26 Sep 2023 00:22:04 +0800 Subject: [PATCH 07/25] Clean up apt lists after installation in Dockerfile --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index c510c98..9ff66ce 100755 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,8 @@ RUN apt-get update && apt-get install -y \ && docker-php-ext-install -j$(nproc) iconv \ && docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/ \ && docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql \ - && docker-php-ext-install -j$(nproc) gd pdo pdo_mysql pdo_pgsql pgsql + && docker-php-ext-install -j$(nproc) gd pdo pdo_mysql pdo_pgsql pgsql \ + && rm -rf /var/lib/apt/lists/* # Prepare files and folders From bb1506c39a925f0ee0da80c827107e1fb4e5b348 Mon Sep 17 00:00:00 2001 From: sstidl Date: Fri, 3 Nov 2023 22:48:12 +0100 Subject: [PATCH 08/25] Update Dockerfile Co-authored-by: Quentame --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ae32f5a..dd261fd 100755 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM php:8.2-apache +FROM php:8-apache # Install extensions RUN apt-get update && apt-get install -y \ From 013e7d56e2c9970d35d08bc977caeb6771497870 Mon Sep 17 00:00:00 2001 From: Stefan STIDL Date: Sat, 4 Nov 2023 00:34:33 +0100 Subject: [PATCH 09/25] fix typo --- results/sanitycheck.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/results/sanitycheck.php b/results/sanitycheck.php index 133b683..335964c 100644 --- a/results/sanitycheck.php +++ b/results/sanitycheck.php @@ -92,7 +92,7 @@ if(!isset($db_type) || $db_type != 'postgresql'){ echo $failed; } ?> -Only required if using sqlite. +Only required if using postgresql. Database check From e0fa5148fe55b7a39123b2f58fb078b3ab691a7f Mon Sep 17 00:00:00 2001 From: Stefan STIDL Date: Sat, 4 Nov 2023 00:35:21 +0100 Subject: [PATCH 10/25] doc: sqlite db persistance explained --- doc_docker.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/doc_docker.md b/doc_docker.md index 178dff7..6e377a2 100755 --- a/doc_docker.md +++ b/doc_docker.md @@ -44,7 +44,7 @@ The test can be accessed on port 80. Here's a list of additional environment variables available in this mode: * __`TITLE`__: Title of your speed test. Default value: `LibreSpeed` -* __`TELEMETRY`__: Whether to enable telemetry or not. Default value: `false` +* __`TELEMETRY`__: Whether to enable telemetry or not. If enabled, you maybe want your data to be persisted. See below. Default value: `false` * __`ENABLE_ID_OBFUSCATION`__: When set to true with telemetry enabled, test IDs are obfuscated, to avoid exposing the database internal sequential IDs. Default value: `false` * __`REDACT_IP_ADDRESSES`__: When set to true with telemetry enabled, IP addresses and hostnames are redacted from the collected telemetry, for better privacy. Default value: `false` * __`PASSWORD`__: Password to access the stats page. If not set, stats page will not allow accesses. @@ -56,6 +56,13 @@ Here's a list of additional environment variables available in this mode: If telemetry is enabled, a stats page will be available at `http://your.server/results/stats.php`, but a password must be specified. +### Persist sqlite database + +Default DB driver is sqlite. The DB file is written to `/database/db.sql`. + +So if you want your data to be persisted over image updates, you have to mount a volume with `-v $PWD/db-dir:/database`. + + ###### Example This command starts LibreSpeed in standalone mode, with the default settings, on port 80: @@ -66,7 +73,7 @@ docker run -e MODE=standalone -p 80:80 -it adolfintel/speedtest This command starts LibreSpeed in standalone mode, with telemetry, ID obfuscation and a stats password, on port 86: ``` -docker run -e MODE=standalone -e TELEMETRY=true -e ENABLE_ID_OBFUSCATION=true -e PASSWORD="yourPasswordHere" -e WEBPORT=86 -p 86:86 -it adolfintel/speedtest +docker run -e MODE=standalone -e TELEMETRY=true -e ENABLE_ID_OBFUSCATION=true -e PASSWORD="yourPasswordHere" -e WEBPORT=86 -p 86:86 -v $PWD/db-dir/:/database -it adolfintel/speedtest ``` ## Multiple Points of Test From 992e24bab68fee4913932b0285ddaf570a984c4d Mon Sep 17 00:00:00 2001 From: sstidl Date: Sat, 4 Nov 2023 02:32:32 +0100 Subject: [PATCH 11/25] Create docker-publish.yml --- .github/workflows/docker-publish.yml | 98 ++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 .github/workflows/docker-publish.yml diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 0000000..cc9007d --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,98 @@ +name: Docker + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +on: + schedule: + - cron: '30 20 * * *' + push: + branches: [ "dev" ] + # Publish semver tags as releases. + tags: [ 'v*.*.*' ] + pull_request: + branches: [ "dev" ] + +env: + # Use docker.io for Docker Hub if empty + REGISTRY: ghcr.io + # github.repository as / + IMAGE_NAME: ${{ github.repository }} + + +jobs: + build: + + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + # This is used to complete the identity challenge + # with sigstore/fulcio when running outside of PRs. + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Install the cosign tool except on PR + # https://github.com/sigstore/cosign-installer + - name: Install cosign + if: github.event_name != 'pull_request' + uses: sigstore/cosign-installer@6e04d228eb30da1757ee4e1dd75a0ec73a653e06 #v3.1.1 + with: + cosign-release: 'v2.1.1' + + # Set up BuildKit Docker container builder to be able to build + # multi-platform images and export cache + # https://github.com/docker/setup-buildx-action + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 + + # Login against a Docker registry except on PR + # https://github.com/docker/login-action + - name: Log into registry ${{ env.REGISTRY }} + if: github.event_name != 'pull_request' + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Extract metadata (tags, labels) for Docker + # https://github.com/docker/metadata-action + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + # Build and push Docker image with Buildx (don't push on PR) + # https://github.com/docker/build-push-action + - name: Build and push Docker image + id: build-and-push + uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0 + with: + context: . + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + # Sign the resulting Docker image digest except on PRs. + # This will only write to the public Rekor transparency log when the Docker + # repository is public to avoid leaking data. If you would like to publish + # transparency data even for private images, pass --force to cosign below. + # https://github.com/sigstore/cosign + - name: Sign the published Docker image + if: ${{ github.event_name != 'pull_request' }} + env: + # https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable + TAGS: ${{ steps.meta.outputs.tags }} + DIGEST: ${{ steps.build-and-push.outputs.digest }} + # This step uses the identity token to provision an ephemeral certificate + # against the sigstore community Fulcio instance. + run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} From cecf591d0f2857aa393f65fc32f79177aee95b77 Mon Sep 17 00:00:00 2001 From: sstidl Date: Sat, 4 Nov 2023 23:14:27 +0100 Subject: [PATCH 12/25] Update docker-publish.yml --- .github/workflows/docker-publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index cc9007d..16c0896 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -6,8 +6,8 @@ name: Docker # documentation. on: - schedule: - - cron: '30 20 * * *' +# schedule: +# - cron: '30 20 * * *' push: branches: [ "dev" ] # Publish semver tags as releases. From 6c92ed8091071b458524f6507db493497a6e27dd Mon Sep 17 00:00:00 2001 From: sstidl Date: Sat, 4 Nov 2023 23:44:07 +0100 Subject: [PATCH 13/25] Update docker-publish.yml --- .github/workflows/docker-publish.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 16c0896..87c8ada 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -9,11 +9,11 @@ on: # schedule: # - cron: '30 20 * * *' push: - branches: [ "dev" ] + branches: [ "*" ] # Publish semver tags as releases. tags: [ 'v*.*.*' ] pull_request: - branches: [ "dev" ] + branches: [ "main","master" ] env: # Use docker.io for Docker Hub if empty @@ -68,6 +68,13 @@ jobs: uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=ref,event=pr + # set latest tag for default branch + type=raw,value=latest,enable={{is_default_branch}} + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} # Build and push Docker image with Buildx (don't push on PR) # https://github.com/docker/build-push-action From 60ea879bc3b1eb93986c32e693bdbeabcedf9872 Mon Sep 17 00:00:00 2001 From: Stefan Stidl Date: Sat, 4 Nov 2023 23:52:59 +0100 Subject: [PATCH 14/25] fix action --- .github/workflows/docker-publish.yml | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 87c8ada..2bf09c4 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -6,14 +6,14 @@ name: Docker # documentation. on: -# schedule: -# - cron: '30 20 * * *' + # schedule: + # - cron: '30 20 * * *' push: - branches: [ "*" ] + branches: ["*"] # Publish semver tags as releases. - tags: [ 'v*.*.*' ] + tags: ["v*.*.*"] pull_request: - branches: [ "main","master" ] + branches: ["{{is_default_branch}}"] env: # Use docker.io for Docker Hub if empty @@ -21,10 +21,8 @@ env: # github.repository as / IMAGE_NAME: ${{ github.repository }} - jobs: build: - runs-on: ubuntu-latest permissions: contents: read @@ -43,7 +41,7 @@ jobs: if: github.event_name != 'pull_request' uses: sigstore/cosign-installer@6e04d228eb30da1757ee4e1dd75a0ec73a653e06 #v3.1.1 with: - cosign-release: 'v2.1.1' + cosign-release: "v2.1.1" # Set up BuildKit Docker container builder to be able to build # multi-platform images and export cache @@ -68,11 +66,11 @@ jobs: uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - tags: | + tags: | type=ref,event=branch type=ref,event=pr - # set latest tag for default branch - type=raw,value=latest,enable={{is_default_branch}} + # set latest tag for default branch + type=raw,value=latest,enable={{is_default_branch}} type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} From 7c05ba084e37e5ec0ddd2cfa57824aad5bab9c5d Mon Sep 17 00:00:00 2001 From: Stefan Stidl Date: Sun, 5 Nov 2023 00:14:48 +0100 Subject: [PATCH 15/25] switch docker image location --- README.md | 2 +- doc_docker.md | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 81d692c..bbe55cb 100755 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ There is a more in-depth installation video here: A template to build an Android client for your LibreSpeed installation is available [here](https://github.com/librespeed/speedtest-android). ## Docker -A docker image is available on the [Docker Hub](https://registry.hub.docker.com/r/adolfintel/speedtest), check our [docker documentation](doc_docker.md) for more info about it +A docker image is available on [GitHub](https://github.com/librespeed/speedtest/pkgs/container/speedtest), check our [docker documentation](doc_docker.md) for more info about it. ## Go backend A Go implementation is available in the [`speedtest-go`](https://github.com/librespeed/speedtest-go) repo, maintained by [Maddie Zhan](https://github.com/maddie). diff --git a/doc_docker.md b/doc_docker.md index 6e377a2..2a6e5e2 100755 --- a/doc_docker.md +++ b/doc_docker.md @@ -1,13 +1,13 @@ -A docker version of LibreSpeed is available on docker hub: [https://hub.docker.com/r/adolfintel/speedtest/](https://hub.docker.com/r/adolfintel/speedtest/) +A docker version of LibreSpeed is available here: [GitHub Packages](https://github.com/librespeed/speedtest/pkgs/container/speedtest) -## Downloading from Docker hub -To download LibreSpeed from the docker hub, use this command: +## Downloading docker image +To download LibreSpeed from the docker repo, use this command: ``` -docker pull adolfintel/speedtest +docker pull ghcr.io/librespeed/speedtest ``` -You will now have a new docker image called `adolfintel/speedtest`. +You will now have a new docker image called `librespeed/speedtest`. ## Docker Compose @@ -18,7 +18,7 @@ version: '3.7' services: speedtest: container_name: speedtest - image: adolfintel/speedtest + image: ghcr.io/librespeed/speedtest:latest restart: always environment: MODE: standalone @@ -67,13 +67,13 @@ So if you want your data to be persisted over image updates, you have to mount a This command starts LibreSpeed in standalone mode, with the default settings, on port 80: ``` -docker run -e MODE=standalone -p 80:80 -it adolfintel/speedtest +docker run -e MODE=standalone -p 80:80 -it ghcr.io/librespeed/speedtest ``` This command starts LibreSpeed in standalone mode, with telemetry, ID obfuscation and a stats password, on port 86: ``` -docker run -e MODE=standalone -e TELEMETRY=true -e ENABLE_ID_OBFUSCATION=true -e PASSWORD="yourPasswordHere" -e WEBPORT=86 -p 86:86 -v $PWD/db-dir/:/database -it adolfintel/speedtest +docker run -e MODE=standalone -e TELEMETRY=true -e ENABLE_ID_OBFUSCATION=true -e PASSWORD="yourPasswordHere" -e WEBPORT=86 -p 86:86 -v $PWD/db-dir/:/database -it ghcr.io/librespeed/speedtest ``` ## Multiple Points of Test @@ -90,7 +90,7 @@ Here's a list of additional environment variables available in this mode: ###### Example: This command starts LibreSpeed in backend mode, with the default settings, on port 80: ``` -docker run -e MODE=backend -p 80:80 -it adolfintel/speedtest +docker run -e MODE=backend -p 80:80 -it ghcr.io/librespeed/speedtest ``` ### Frontend mode @@ -137,5 +137,5 @@ Here's a list of additional environment variables available in this mode: ###### Example This command starts LibreSpeed in frontend mode, with a given `servers.json` file, and with telemetry, ID obfuscation, and a stats password: ``` -docker run -e MODE=frontend -e TELEMETRY=true -e ENABLE_ID_OBFUSCATION=true -e PASSWORD="yourPasswordHere" -v $(pwd)/servers.json:/servers.json -p 80:80 -it adolfintel/speedtest +docker run -e MODE=frontend -e TELEMETRY=true -e ENABLE_ID_OBFUSCATION=true -e PASSWORD="yourPasswordHere" -v $(pwd)/servers.json:/servers.json -p 80:80 -it ghcr.io/librespeed/speedtest ``` From e468c3d0689b7e5564b55247069e58f070430f29 Mon Sep 17 00:00:00 2001 From: Stefan Stidl Date: Sun, 5 Nov 2023 00:20:39 +0100 Subject: [PATCH 16/25] without image signing --- .github/workflows/docker-publish.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 2bf09c4..7e7266c 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -86,18 +86,3 @@ jobs: labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max - - # Sign the resulting Docker image digest except on PRs. - # This will only write to the public Rekor transparency log when the Docker - # repository is public to avoid leaking data. If you would like to publish - # transparency data even for private images, pass --force to cosign below. - # https://github.com/sigstore/cosign - - name: Sign the published Docker image - if: ${{ github.event_name != 'pull_request' }} - env: - # https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable - TAGS: ${{ steps.meta.outputs.tags }} - DIGEST: ${{ steps.build-and-push.outputs.digest }} - # This step uses the identity token to provision an ephemeral certificate - # against the sigstore community Fulcio instance. - run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} From b1aa63259c9078b69302257bc0552fa940cf5ac8 Mon Sep 17 00:00:00 2001 From: Stefan Stidl Date: Sun, 5 Nov 2023 00:35:46 +0100 Subject: [PATCH 17/25] remove signing --- .github/workflows/docker-publish.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 7e7266c..0416c2d 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -35,14 +35,6 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 - # Install the cosign tool except on PR - # https://github.com/sigstore/cosign-installer - - name: Install cosign - if: github.event_name != 'pull_request' - uses: sigstore/cosign-installer@6e04d228eb30da1757ee4e1dd75a0ec73a653e06 #v3.1.1 - with: - cosign-release: "v2.1.1" - # Set up BuildKit Docker container builder to be able to build # multi-platform images and export cache # https://github.com/docker/setup-buildx-action From 63583cb3f46bf0f928ee48be47018a55d39f6c2c Mon Sep 17 00:00:00 2001 From: Stefan Stidl Date: Sun, 5 Nov 2023 01:05:50 +0100 Subject: [PATCH 18/25] switch units to Mbit/s --- doc.md | 4 ++-- docker/frontend.php | 4 ++-- docker/standalone.php | 4 ++-- example-multipleServers-full.html | 4 ++-- example-multipleServers-pretty.html | 4 ++-- example-singleServer-customSettings.html | 4 ++-- example-singleServer-full.html | 4 ++-- example-singleServer-gauges.html | 4 ++-- example-singleServer-pretty.html | 4 ++-- example-singleServer-progressBar.html | 4 ++-- results/index.php | 2 +- speedtest.js | 4 ++-- 12 files changed, 23 insertions(+), 23 deletions(-) diff --git a/doc.md b/doc.md index 51b5db9..7321419 100755 --- a/doc.md +++ b/doc.md @@ -507,8 +507,8 @@ You can think of this as a finite state machine. These are the states (use getSt While in state 1, you can only add test points, you cannot change the test settings. When you're done, use selectServer(callback) to select the test point with the lowest ping. This is asynchronous, when it's done, it will call your callback function and move to state 2. Calling setSelectedServer(server) will manually select a server and move to state 2. * __2__: test point selected, ready to start the test. Use `start()` to begin, this will move to state 3 * __3__: test running. Here, your `onupdate` event callback will be called periodically, with data coming from the worker about speed and progress. A data object will be passed to your `onupdate` function, with the following items: - - `dlStatus`: download speed in mbps - - `ulStatus`: upload speed in mbps + - `dlStatus`: download speed in Mbit/s + - `ulStatus`: upload speed in Mbit/s - `pingStatus`: ping in ms - `jitterStatus`: jitter in ms - `dlProgress`: progress of the download test as a float 0-1 diff --git a/docker/frontend.php b/docker/frontend.php index 8e801b6..33da560 100755 --- a/docker/frontend.php +++ b/docker/frontend.php @@ -409,13 +409,13 @@ function initUI(){
Download
-
Mbps
+
Mbit/s
Upload
-
Mbps
+
Mbit/s
diff --git a/docker/standalone.php b/docker/standalone.php index 62a4982..81dd318 100755 --- a/docker/standalone.php +++ b/docker/standalone.php @@ -301,13 +301,13 @@ function initUI(){
Download
-
Mbps
+
Mbit/s
Upload
-
Mbps
+
Mbit/s
diff --git a/example-multipleServers-full.html b/example-multipleServers-full.html index 065e3d5..ed59473 100755 --- a/example-multipleServers-full.html +++ b/example-multipleServers-full.html @@ -424,13 +424,13 @@ function initUI(){
Download
-
Mbps
+
Mbit/s
Upload
-
Mbps
+
Mbit/s
diff --git a/example-multipleServers-pretty.html b/example-multipleServers-pretty.html index 4316eab..742238b 100755 --- a/example-multipleServers-pretty.html +++ b/example-multipleServers-pretty.html @@ -212,12 +212,12 @@ function I(id){return document.getElementById(id);}
Download
-
Mbps
+
Mbit/s
Upload
-
Mbps
+
Mbit/s
diff --git a/example-singleServer-customSettings.html b/example-singleServer-customSettings.html index b1c0cfb..1a06f89 100755 --- a/example-singleServer-customSettings.html +++ b/example-singleServer-customSettings.html @@ -157,12 +157,12 @@ function I(id){return document.getElementById(id);}
Download
-
Mbps
+
Mbit/s
Upload
-
Mbps
+
Mbit/s
diff --git a/example-singleServer-full.html b/example-singleServer-full.html index d72aa66..2627615 100755 --- a/example-singleServer-full.html +++ b/example-singleServer-full.html @@ -298,13 +298,13 @@ function initUI(){
Download
-
Mbps
+
Mbit/s
Upload
-
Mbps
+
Mbit/s
diff --git a/example-singleServer-gauges.html b/example-singleServer-gauges.html index 9a49705..0b6c388 100755 --- a/example-singleServer-gauges.html +++ b/example-singleServer-gauges.html @@ -242,13 +242,13 @@ function initUI(){
Download
-
Mbps
+
Mbit/s
Upload
-
Mbps
+
Mbit/s
diff --git a/example-singleServer-pretty.html b/example-singleServer-pretty.html index 7715535..eca431b 100755 --- a/example-singleServer-pretty.html +++ b/example-singleServer-pretty.html @@ -160,12 +160,12 @@ function I(id){return document.getElementById(id);}
Download
-
Mbps
+
Mbit/s
Upload
-
Mbps
+
Mbit/s
diff --git a/example-singleServer-progressBar.html b/example-singleServer-progressBar.html index f9e7007..ce037b6 100755 --- a/example-singleServer-progressBar.html +++ b/example-singleServer-progressBar.html @@ -180,12 +180,12 @@ function I(id){return document.getElementById(id);}
Download
-
Mbps
+
Mbit/s
Upload
-
Mbps
+
Mbit/s
diff --git a/results/index.php b/results/index.php index ad6beca..4559315 100755 --- a/results/index.php +++ b/results/index.php @@ -162,7 +162,7 @@ function drawImage($speedtest) $POSITION_Y_WATERMARK = 223 * $SCALE; // configure labels - $MBPS_TEXT = 'Mbps'; + $MBPS_TEXT = 'Mbit/s'; $MS_TEXT = 'ms'; $PING_TEXT = 'Ping'; $JIT_TEXT = 'Jitter'; diff --git a/speedtest.js b/speedtest.js index 143ce1f..ee8ab22 100755 --- a/speedtest.js +++ b/speedtest.js @@ -28,8 +28,8 @@ While in state 1, you can only add test points, you cannot change the test settings. When you're done, use selectServer(callback) to select the test point with the lowest ping. This is asynchronous, when it's done, it will call your callback function and move to state 2. Calling setSelectedServer(server) will manually select a server and move to state 2. - 2: test point selected, ready to start the test. Use start() to begin, this will move to state 3 - 3: test running. Here, your onupdate event callback will be called periodically, with data coming from the worker about speed and progress. A data object will be passed to your onupdate function, with the following items: - - dlStatus: download speed in mbps - - ulStatus: upload speed in mbps + - dlStatus: download speed in Mbit/s + - ulStatus: upload speed in Mbit/s - pingStatus: ping in ms - jitterStatus: jitter in ms - dlProgress: progress of the download test as a float 0-1 From 338b2c27ef645a7c627c484c3b001b9d2818dac7 Mon Sep 17 00:00:00 2001 From: Stefan Stidl Date: Sun, 5 Nov 2023 01:14:02 +0100 Subject: [PATCH 19/25] move examples to folder --- .../example-multipleServers-full.html | 0 .../example-multipleServers-pretty.html | 0 .../example-singleServer-basic.html | 0 .../example-singleServer-chart.html | 0 .../example-singleServer-customSettings.html | 0 .../example-singleServer-full.html | 0 .../example-singleServer-gauges.html | 0 .../example-singleServer-pretty.html | 0 .../example-singleServer-progressBar.html | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename example-multipleServers-full.html => examples/example-multipleServers-full.html (100%) rename example-multipleServers-pretty.html => examples/example-multipleServers-pretty.html (100%) rename example-singleServer-basic.html => examples/example-singleServer-basic.html (100%) rename example-singleServer-chart.html => examples/example-singleServer-chart.html (100%) rename example-singleServer-customSettings.html => examples/example-singleServer-customSettings.html (100%) rename example-singleServer-full.html => examples/example-singleServer-full.html (100%) rename example-singleServer-gauges.html => examples/example-singleServer-gauges.html (100%) rename example-singleServer-pretty.html => examples/example-singleServer-pretty.html (100%) rename example-singleServer-progressBar.html => examples/example-singleServer-progressBar.html (100%) diff --git a/example-multipleServers-full.html b/examples/example-multipleServers-full.html similarity index 100% rename from example-multipleServers-full.html rename to examples/example-multipleServers-full.html diff --git a/example-multipleServers-pretty.html b/examples/example-multipleServers-pretty.html similarity index 100% rename from example-multipleServers-pretty.html rename to examples/example-multipleServers-pretty.html diff --git a/example-singleServer-basic.html b/examples/example-singleServer-basic.html similarity index 100% rename from example-singleServer-basic.html rename to examples/example-singleServer-basic.html diff --git a/example-singleServer-chart.html b/examples/example-singleServer-chart.html similarity index 100% rename from example-singleServer-chart.html rename to examples/example-singleServer-chart.html diff --git a/example-singleServer-customSettings.html b/examples/example-singleServer-customSettings.html similarity index 100% rename from example-singleServer-customSettings.html rename to examples/example-singleServer-customSettings.html diff --git a/example-singleServer-full.html b/examples/example-singleServer-full.html similarity index 100% rename from example-singleServer-full.html rename to examples/example-singleServer-full.html diff --git a/example-singleServer-gauges.html b/examples/example-singleServer-gauges.html similarity index 100% rename from example-singleServer-gauges.html rename to examples/example-singleServer-gauges.html diff --git a/example-singleServer-pretty.html b/examples/example-singleServer-pretty.html similarity index 100% rename from example-singleServer-pretty.html rename to examples/example-singleServer-pretty.html diff --git a/example-singleServer-progressBar.html b/examples/example-singleServer-progressBar.html similarity index 100% rename from example-singleServer-progressBar.html rename to examples/example-singleServer-progressBar.html From 9b8faee10dbdcf7fb8493d40ab387c11dc664556 Mon Sep 17 00:00:00 2001 From: Stefan Stidl Date: Sun, 5 Nov 2023 02:08:11 +0100 Subject: [PATCH 20/25] fix ipinfo parsing --- backend/getIP.php | 110 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 92 insertions(+), 18 deletions(-) diff --git a/backend/getIP.php b/backend/getIP.php index 0b6267d..7c57a93 100755 --- a/backend/getIP.php +++ b/backend/getIP.php @@ -76,7 +76,7 @@ function getIpInfoTokenString() return ''; } - return '?token='.$IPINFO_APIKEY; + return '?token=' . $IPINFO_APIKEY; } /** @@ -86,7 +86,7 @@ function getIpInfoTokenString() */ function getIspInfo($ip) { - $json = file_get_contents('https://ipinfo.io/'.$ip.'/json'.getIpInfoTokenString()); + $json = file_get_contents('https://ipinfo.io/' . $ip . '/json' . getIpInfoTokenString()); if (!is_string($json)) { return null; } @@ -106,17 +106,91 @@ function getIspInfo($ip) */ function getIsp($rawIspInfo) { - if ( - !is_array($rawIspInfo) - || !array_key_exists('org', $rawIspInfo) - || !is_string($rawIspInfo['org']) - || empty($rawIspInfo['org']) - ) { - return 'Unknown ISP'; + if (is_array($rawIspInfo)) { + /* variant with no token + has json like: + { + "ip": "xxx.xxx.xxx.xxx", + "hostname": "example.com", + "city": "Vienna", + "region": "Vienna", + "country": "AT", + "loc": "48.2085,16.3721", + "org": "ASxxxx T-Mobile Austria GmbH", + "postal": "nnnn", + "timezone": "Europe/Vienna", + "readme": "https://ipinfo.io/missingauth" + } + */ + if ( + array_key_exists('org', $rawIspInfo) + && is_string($rawIspInfo['org']) + && !empty($rawIspInfo['org']) + ) { + // Remove AS##### from ISP name, if present + return preg_replace('/AS\\d+\\s/', '', $rawIspInfo['org']); + } + + /* + variant with valid token has json: + { + "ip": "xxx.xxx.xxx.xxx", + "hostname": "example.com", + "city": "Vienna", + "region": "Vienna", + "country": "AT", + "loc": "48.2085,16.3721", + "postal": "1010", + "timezone": "Europe/Vienna", + "asn": { + "asn": "ASxxxx", + "name": "T-Mobile Austria GmbH", + "domain": "t-mobile.at", + "route": "xxx.xxx.xxx.xxx/xx", + "type": "isp" + }, + "company": { + "name": "XX", + "domain": "example.com", + "type": "isp" + }, + "privacy": { + "vpn": true, + "proxy": false, + "tor": false, + "relay": false, + "hosting": false, + "service": "" + }, + "abuse": { + "address": "...", + "country": "AT", + "email": "abuse@example.com", + "name": "XXX", + "network": "xxx.xxx.xxx.xxx-xxx.xxx.xxx.xxx", + "phone": "" + }, + "domains": { + "total": 0, + "domains": [ + + ] + } + } + */ + if ( + array_key_exists('asn', $rawIspInfo) + && is_string($rawIspInfo['asn']) + && !empty($rawIspInfo['asn']) + && array_key_exists('name', $rawIspInfo['asn']) + && is_string($rawIspInfo['asn']['name']) + ) { + // Remove AS##### from ISP name, if present + return $rawIspInfo['asn']['name']; + } } - // Remove AS##### from ISP name, if present - return preg_replace('/AS\\d+\\s/', '', $rawIspInfo['org']); + return 'Unknown ISP'; } /** @@ -135,7 +209,7 @@ function getServerLocation() return $serverLoc; } - $json = file_get_contents('https://ipinfo.io/json'.getIpInfoTokenString()); + $json = file_get_contents('https://ipinfo.io/json' . getIpInfoTokenString()); if (!is_string($json)) { return null; } @@ -151,7 +225,7 @@ function getServerLocation() } $serverLoc = $details['loc']; - $cacheData = " Date: Sun, 5 Nov 2023 02:27:49 +0100 Subject: [PATCH 21/25] fix regression on getIpinfo --- backend/getIP.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/getIP.php b/backend/getIP.php index 7c57a93..c7501c4 100755 --- a/backend/getIP.php +++ b/backend/getIP.php @@ -180,7 +180,7 @@ function getIsp($rawIspInfo) */ if ( array_key_exists('asn', $rawIspInfo) - && is_string($rawIspInfo['asn']) + && is_array($rawIspInfo['asn']) && !empty($rawIspInfo['asn']) && array_key_exists('name', $rawIspInfo['asn']) && is_string($rawIspInfo['asn']['name']) From 26624911322a966977be3645acab4f9cc57ce4df Mon Sep 17 00:00:00 2001 From: sstidl Date: Mon, 6 Nov 2023 10:43:06 +0100 Subject: [PATCH 22/25] removed trailing whitespaces --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- .gitignore | 1 + Dockerfile | 2 +- README.md | 6 +-- backend/getIP.php | 4 +- doc.md | 50 ++++++++++---------- doc_docker.md | 2 +- docker/entrypoint.sh | 4 +- examples/example-multipleServers-pretty.html | 2 +- results/json.php | 2 +- results/sanitycheck.php | 4 +- results/telemetry_db.php | 26 +++++----- results/telemetry_mssql.sql | 2 +- results/telemetry_postgresql.sql | 6 +-- speedtest.js | 6 +-- 15 files changed, 60 insertions(+), 59 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index f4804cb..f6726e3 100755 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -24,5 +24,5 @@ Browser, OS, type of connection, unusual software, ... What should have happened ## Screenshots -If necessary, add screenshots of the test. +If necessary, add screenshots of the test. F12 > Network screenshots can be particularly useful diff --git a/.gitignore b/.gitignore index c53159e..302804e 100755 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ results/idObfuscation_salt.php backend/getIP_serverLocation.php +db-dir/ diff --git a/Dockerfile b/Dockerfile index 0d34837..212779f 100755 --- a/Dockerfile +++ b/Dockerfile @@ -29,7 +29,7 @@ COPY docker/servers.json /servers.json COPY docker/*.php /speedtest/ COPY docker/entrypoint.sh / -# Prepare default environment variables +# Prepare default environment variables ENV TITLE=LibreSpeed ENV MODE=standalone ENV PASSWORD=password diff --git a/README.md b/README.md index 23e4a6f..eba9e0b 100755 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ This is a very lightweight speed test implemented in Javascript, using XMLHttpRe [Take a speed test](https://librespeed.org) ## Compatibility -All modern browsers are supported: IE11, latest Edge, latest Chrome, latest Firefox, latest Safari. +All modern browsers are supported: IE11, latest Edge, latest Chrome, latest Firefox, latest Safari. Works with mobile versions too. ## Features @@ -61,8 +61,8 @@ A Go implementation is available in the [`speedtest-go`](https://github.com/libr A partial Node.js implementation is available in the `node` branch, developed by [dunklesToast](https://github.com/dunklesToast). It's not recommended to use at the moment. ## Donate -[![Donate with Liberapay](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/fdossena/donate) -[Donate with PayPal](https://www.paypal.me/sineisochronic) +[![Donate with Liberapay](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/fdossena/donate) +[Donate with PayPal](https://www.paypal.me/sineisochronic) ## License Copyright (C) 2016-2022 Federico Dossena diff --git a/backend/getIP.php b/backend/getIP.php index c7501c4..d82711d 100755 --- a/backend/getIP.php +++ b/backend/getIP.php @@ -108,7 +108,7 @@ function getIsp($rawIspInfo) { if (is_array($rawIspInfo)) { /* variant with no token - has json like: + has json like: { "ip": "xxx.xxx.xxx.xxx", "hostname": "example.com", @@ -173,7 +173,7 @@ function getIsp($rawIspInfo) "domains": { "total": 0, "domains": [ - + ] } } diff --git a/doc.md b/doc.md index 7321419..b30a01a 100755 --- a/doc.md +++ b/doc.md @@ -1,6 +1,6 @@ # LibreSpeed -> by Federico Dossena +> by Federico Dossena > Version 5.2.4 > [https://github.com/librespeed/speedtest/](https://github.com/librespeed/speedtest/) @@ -109,7 +109,7 @@ A basic front-end for visualizing and searching tests by ID is available in `res A login is required to access the interface. __Important__: change the default password in `results/telemetry_settings.php`. #### The end -Now that the test is installed, rename one of the examples to `index.html` and delete the other examples. +Now that the test is installed, rename one of the examples to `index.html` and delete the other examples. The best starting point for most people is `example-singleServer-gauges.html`. If you want to use telemetry and results sharing, use `example-singleServer-full.html` instead. If you're not using telemetry and results sharing, you can delete the `results` folder too. @@ -459,7 +459,7 @@ s.selectServer(function(server){ //do something }) ``` -The `selectServer` function is asynchronous in order to avoid freeing the UI, and it will run a callback function when it is done choosing the server with the lowest ping. +The `selectServer` function is asynchronous in order to avoid freeing the UI, and it will run a callback function when it is done choosing the server with the lowest ping. The `server` argument is the selected server, and you can display it in the UI if you want. __You cannot start the test until the selection is done!__ You can also set the test point manually (for instance, from a combobox in the UI): @@ -483,7 +483,7 @@ s.abort(); When the test is finished, you can run it again if you want, or you can just destroy `s`. ## Implementation details -The purpose of this section is to help developers who want to make changes to the inner workings of the speed test. +The purpose of this section is to help developers who want to make changes to the inner workings of the speed test. It will be divided into 4 sections: `speedtest.js`, `speedtest_worker.js`, the `backend` files and the `results` files. ### `speedtest.js` @@ -515,7 +515,7 @@ You can think of this as a finite state machine. These are the states (use getSt - `ulProgress`: progress of the upload test as a float 0-1 - `pingProgress`: progress of the ping/jitter test as a float 0-1 - `testState`: state of the test (-1=not started, 0=starting, 1=download test, 2=ping+jitter test, 3=upload test, 4=finished, 5=aborted) - - `clientIp`: IP address of the client performing the test (and optionally ISP and distance) + - `clientIp`: IP address of the client performing the test (and optionally ISP and distance) At the end of the test, the `onend` function will be called, with a boolean specifying whether the test was aborted or if it ended normally. The test can be aborted at any time with `abort()`. At the end of the test, it will move to state 4 @@ -575,7 +575,7 @@ Starts the test. Note (multiple points of test): the selected server will be added to the `telemetry_extra` string. If this string was already set, then `telemetry_extra` will be a JSON string containing both the server and the original string -During the test, the `onupdate(data)` callback function will be called periodically with data from the worker. +During the test, the `onupdate(data)` callback function will be called periodically with data from the worker. At the end of the test, the `onend(aborted)` function will be called with a boolean telling you if the test was aborted or if it ended normally. ##### abort() @@ -747,8 +747,8 @@ This will point to our static files and set the test to only do ping/jitter, dow These are the most common issues reported by users, and how to fix them. If you still need help, contact me at [info@fdossena.com](mailto:info@fdossena.com). #### Download test gives very low result -Are garbage.php and empty.php (or your replacements) reachable? -Press F12, select network and start the test. Do you see errors? (cancelled requests are not errors) +Are garbage.php and empty.php (or your replacements) reachable? +Press F12, select network and start the test. Do you see errors? (cancelled requests are not errors) If a small download starts, open it in a text editor. Does it say it's missing openssl_random_pseudo_bytes()? In this case, install OpenSSL (this is usually included when you install Apache and PHP on most distros). #### Upload test is inaccurate, and/or I see lag spikes @@ -764,15 +764,15 @@ You're running the test on localhost, therefore it is trying to measure the spee Make sure your server is sending the `Connection:keep-alive` header #### The server is behind a load balancer, proxy, etc. and I get the wrong IP address -Edit getIP.php and replace lines 14-23 with what is more appropriate in your scenario. +Edit getIP.php and replace lines 14-23 with what is more appropriate in your scenario. Example: `$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];` #### The results sharing just generates a blank image -If the image doesn't display and the browser displays a broken image icon, FreeType2 is not installed or configured properly. +If the image doesn't display and the browser displays a broken image icon, FreeType2 is not installed or configured properly. If the image is blank, this usually happens because PHP can't find the font files inside the `results` folder. You can fix your PHP config or edit `results/index.php` and use absolute paths for the fonts. This is a [known issue with PHP](http://php.net/manual/en/function.imagefttext.php) and no real solution is known. #### My server is behind Cloudflare and I can't reach full speed on some of the tests -This is not a speed test related issue, as it can be replicated in virtually any HTTP file upload/download. +This is not a speed test related issue, as it can be replicated in virtually any HTTP file upload/download. Go to your domain's DNS settings and change "DNS and HTTP proxy (CDN)" to "DNS only", and wait for the settings to be applied (can take a few minutes). #### On Windows Server, using IIS, the upload test doesn't work, CORS errors are visible in the console @@ -781,26 +781,26 @@ This is a configuration issue. Make a file called web.config in wwwroot and adap - - + + - - - - - - - + + + + + + + - + - - + + ``` #### ID obfuscation doesn't work (incorrect output, blank results image) -ID obfuscation only works on 64-bit PHP (requires PHP_INT_SIZE to be 8). +ID obfuscation only works on 64-bit PHP (requires PHP_INT_SIZE to be 8). Note that older versions of PHP 5 on Windows use PHP_INT_SIZE of 4, even if they're 64 bit. If you're in this situation, update your PHP install. Also, make sure that the web server has write permission on the `results` folder. @@ -818,7 +818,7 @@ Also, make sure that the web server has write permission on the `results` folder ## Contributing Since this is an open source project, you can modify it. -If you made some changes that you think should make it into the main project, send a Pull Request on GitHub, or contact me at [info@fdossena.com](mailto:info@fdossena.com). +If you made some changes that you think should make it into the main project, send a Pull Request on GitHub, or contact me at [info@fdossena.com](mailto:info@fdossena.com). We don't require you to use a specific coding convention, write the code however you want and we'll change the formatting if necessary. Donations are also appreciated: you can donate with [PayPal](https://www.paypal.me/sineisochronic) or [Liberapay](https://liberapay.com/fdossena/donate). diff --git a/doc_docker.md b/doc_docker.md index 2a6e5e2..85541a7 100755 --- a/doc_docker.md +++ b/doc_docker.md @@ -120,7 +120,7 @@ In frontend mode, LibreSpeed serves clients the Web UI and a list of servers. To ``` Note: if a server only supports HTTP or HTTPS, specify the protocol in the server field. If it supports both, just use `//`. * Mount this file to `/servers.json` in the container (example at the end of this file) - + The test can be accessed on port 80. Here's a list of additional environment variables available in this mode: diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index d08ff05..659cb2b 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -37,7 +37,7 @@ fi # Apply Telemetry settings when running in standalone or frontend mode and telemetry is enabled if [[ "$TELEMETRY" == "true" && ( "$MODE" == "frontend" || "$MODE" == "standalone" ) ]]; then cp -r /speedtest/results /var/www/html/results - + if [ "$MODE" == "frontend" ]; then mkdir /var/www/html/backend cp /speedtest/backend/getIP_util.php /var/www/html/backend @@ -82,7 +82,7 @@ chown -R www-data /var/www/html/* # Allow selection of Apache port for network_mode: host if [ "$WEBPORT" != "80" ]; then sed -i "s/^Listen 80\$/Listen $WEBPORT/g" /etc/apache2/ports.conf - sed -i "s/*:80>/*:$WEBPORT>/g" /etc/apache2/sites-available/000-default.conf + sed -i "s/*:80>/*:$WEBPORT>/g" /etc/apache2/sites-available/000-default.conf fi echo "Done, Starting APACHE" diff --git a/examples/example-multipleServers-pretty.html b/examples/example-multipleServers-pretty.html index 742238b..43b3052 100755 --- a/examples/example-multipleServers-pretty.html +++ b/examples/example-multipleServers-pretty.html @@ -70,7 +70,7 @@ function loadServers(){ //called when the page is fully loaded s.addTestPoints(SPEEDTEST_SERVERS); selectServer(); } - + } diff --git a/results/json.php b/results/json.php index 4a75c45..9730d20 100755 --- a/results/json.php +++ b/results/json.php @@ -55,5 +55,5 @@ if (!is_array($speedtest)) { echo '{}'; } $speedtest = formatSpeedtestData($speedtest); - + echo json_encode(array('timestamp'=>$speedtest['timestamp'],'download'=>$speedtest['dl'],'upload'=>$speedtest['ul'],'ping'=>$speedtest['ping'],'jitter'=>$speedtest['jitter'],'ispinfo'=>$speedtest['ispinfo'])); diff --git a/results/sanitycheck.php b/results/sanitycheck.php index 335964c..ed24ff0 100644 --- a/results/sanitycheck.php +++ b/results/sanitycheck.php @@ -171,7 +171,7 @@ echo ' '; print_r($pdo); if(!isset($pdo)){ echo 'got nothing'; -} +} if($pdo == false){ echo 'got a false'; } @@ -186,4 +186,4 @@ if (($pdo instanceof PDO)) { $speedtest = getSpeedtestUserById(1); print_r ($speedtest); */ -?> \ No newline at end of file +?> diff --git a/results/telemetry_db.php b/results/telemetry_db.php index e516638..46b8bf7 100755 --- a/results/telemetry_db.php +++ b/results/telemetry_db.php @@ -15,7 +15,7 @@ function getPdo($returnErrorMessage = false) ) { if($returnErrorMessage){ return 'missing TELEMETRY_SETTINGS_FILE'; - } + } return false; } @@ -24,7 +24,7 @@ function getPdo($returnErrorMessage = false) if (!isset($db_type)) { if($returnErrorMessage){ return "db_type not set in '" . TELEMETRY_SETTINGS_FILE . "'"; - } + } return false; } @@ -41,7 +41,7 @@ function getPdo($returnErrorMessage = false) )) { if($returnErrorMessage){ return "Required MSSQL database settings missing in '" . TELEMETRY_SETTINGS_FILE . "'"; - } + } return false; } @@ -53,7 +53,7 @@ function getPdo($returnErrorMessage = false) ) { if($returnErrorMessage){ return "Required MSSQL database settings missing in '" . TELEMETRY_SETTINGS_FILE . "'"; - } + } return false; } $dsn = 'sqlsrv:' @@ -84,7 +84,7 @@ function getPdo($returnErrorMessage = false) )) { if($returnErrorMessage){ return "Required mysql database settings missing in '" . TELEMETRY_SETTINGS_FILE . "'"; - } + } return false; } @@ -100,7 +100,7 @@ function getPdo($returnErrorMessage = false) if (!isset($Sqlite_db_file)) { if($returnErrorMessage){ return "Required sqlite database settings missing in '" . TELEMETRY_SETTINGS_FILE . "'"; - } + } return false; } @@ -135,7 +135,7 @@ function getPdo($returnErrorMessage = false) )) { if($returnErrorMessage){ return "Required postgresql database settings missing in '" . TELEMETRY_SETTINGS_FILE . "'"; - } + } return false; } @@ -148,13 +148,13 @@ function getPdo($returnErrorMessage = false) } catch (Exception $e) { if($returnErrorMessage){ return $e->getMessage(); - } + } return false; } if($returnErrorMessage){ return "db_type '" . $db_type . "' not supported"; - } + } return false; } @@ -179,7 +179,7 @@ function insertSpeedtestUser($ip, $ispinfo, $extra, $ua, $lang, $dl, $ul, $ping, if (!($pdo instanceof PDO)) { if($returnExceptionOnError){ return new Exception("Failed to get database connection object"); - } + } return false; } @@ -196,7 +196,7 @@ function insertSpeedtestUser($ip, $ispinfo, $extra, $ua, $lang, $dl, $ul, $ping, } catch (Exception $e) { if($returnExceptionOnError){ return $e; - } + } return false; } @@ -222,7 +222,7 @@ function getSpeedtestUserById($id,$returnExceptionOnError = false) if (!($pdo instanceof PDO)) { if($returnExceptionOnError){ return new Exception("Failed to get database connection object"); - } + } return false; } @@ -243,7 +243,7 @@ function getSpeedtestUserById($id,$returnExceptionOnError = false) } catch (Exception $e) { if($returnExceptionOnError){ return $e; - } + } return false; } diff --git a/results/telemetry_mssql.sql b/results/telemetry_mssql.sql index 6c68d84..2fa3b55 100644 --- a/results/telemetry_mssql.sql +++ b/results/telemetry_mssql.sql @@ -17,7 +17,7 @@ CREATE TABLE [dbo].[speedtest_users]( [ping] [nvarchar](max) NULL, [jitter] [nvarchar](max) NULL, [log] [nvarchar](max) NULL, - CONSTRAINT [PK_speedtest_users] PRIMARY KEY CLUSTERED + CONSTRAINT [PK_speedtest_users] PRIMARY KEY CLUSTERED ( [id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] diff --git a/results/telemetry_postgresql.sql b/results/telemetry_postgresql.sql index e28e8ef..bdc6284 100755 --- a/results/telemetry_postgresql.sql +++ b/results/telemetry_postgresql.sql @@ -15,14 +15,14 @@ SET client_min_messages = warning; SET row_security = off; -- --- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: +-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: -- CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; -- --- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: +-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: -- COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language'; @@ -68,7 +68,7 @@ CREATE SEQUENCE speedtest_users_id_seq CACHE 1; -- Commented out the following line because it assumes the user of the speedtest server, @bplower --- ALTER TABLE speedtest_users_id_seq OWNER TO speedtest; +-- ALTER TABLE speedtest_users_id_seq OWNER TO speedtest; -- -- Name: speedtest_users_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: speedtest diff --git a/speedtest.js b/speedtest.js index ee8ab22..2299c51 100755 --- a/speedtest.js +++ b/speedtest.js @@ -8,9 +8,9 @@ /* This is the main interface between your webpage and the speed test. It hides the speed test web worker to the page, and provides many convenient functions to control the test. - + The best way to learn how to use this is to look at the basic example, but here's some documentation. - + To initialize the test, create a new Speedtest object: var s=new Speedtest(); Now you can think of this as a finite state machine. These are the states (use getState() to see them): @@ -36,7 +36,7 @@ - ulProgress: progress of the upload test as a float 0-1 - pingProgress: progress of the ping/jitter test as a float 0-1 - testState: state of the test (-1=not started, 0=starting, 1=download test, 2=ping+jitter test, 3=upload test, 4=finished, 5=aborted) - - clientIp: IP address of the client performing the test (and optionally ISP and distance) + - clientIp: IP address of the client performing the test (and optionally ISP and distance) At the end of the test, the onend function will be called, with a boolean specifying whether the test was aborted or if it ended normally. The test can be aborted at any time with abort(). At the end of the test, it will move to state 4 From c4c87bc144aa5f238ec7511408c7acda3b83cc53 Mon Sep 17 00:00:00 2001 From: sstidl Date: Wed, 8 Nov 2023 12:21:59 +0000 Subject: [PATCH 23/25] integrate ios favicon closes #400 --- docker/frontend.php | 2 ++ docker/standalone.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docker/frontend.php b/docker/frontend.php index 33da560..724fdc0 100755 --- a/docker/frontend.php +++ b/docker/frontend.php @@ -3,6 +3,8 @@ + + From 05261e608ce8390ff47b85a9ca65da0a6c938c57 Mon Sep 17 00:00:00 2001 From: sstidl Date: Sat, 18 Nov 2023 14:15:42 +0000 Subject: [PATCH 24/25] set single-server-full as index --- examples/example-singleServer-full.html => index.html | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/example-singleServer-full.html => index.html (100%) diff --git a/examples/example-singleServer-full.html b/index.html similarity index 100% rename from examples/example-singleServer-full.html rename to index.html From a6c0818b665eb06dbe2eb8d4fc609c345e0e8f9a Mon Sep 17 00:00:00 2001 From: sstidl Date: Sat, 2 Dec 2023 11:58:20 +0100 Subject: [PATCH 25/25] Update docker-publish.yml: add arm64 --- .github/workflows/docker-publish.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 0416c2d..6353b50 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -73,6 +73,7 @@ jobs: uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0 with: context: . + platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }}