- Load server list dynamically from servers.json for Docker frontend/dual modes
- Copy servers.json to web root in entrypoint.sh for frontend/dual modes
- Change back link from href="/" to href="./" for subdirectory installs
- Use binary search for visible chart data range (O(log n) vs O(n))
- Add 200ms minimum interval between pings to limit sample rate
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a prolonged ping-based stability test with real-time canvas chart,
stats (avg/min/max/jitter/packet loss), stability rating, external ping
targets, CSV export, and Docker support. Link from main page to stability test.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build an array of {idx, server} pairs before sorting so the original
SPEEDTEST_SERVERS index is carried through, eliminating the per-option
indexOf call.
Parse server names more robustly for sorting:
- "City, Country, Provider" → use second part as country
- "City, Country (1) (Hetzner)" → strip parentheticals from country
- "Frankfurt, Germany (FRA01)" → country is "Germany" not "Germany (FRA01)"
Address code review findings:
- Sort a shallow copy instead of mutating the caller's array
- Add null guard on server.name to handle malformed entries
- Use original SPEEDTEST_SERVERS index for classic UI option values
Sort the server dropdown by country first, then by city within the same
country. This makes it easier to find servers in a specific country when
the list is long. Applies to both modern and classic UIs.
ca-certificates-bundle (which provides /etc/ssl/certs/ca-certificates.crt)
is already pulled in transitively by apache2 / php-apache2 on alpine:3.23,
so live HTTPS calls from PHP work today (verified with file_get_contents
against ipinfo.io). But the master image (FROM php:8-alpine) installs
the full ca-certificates package explicitly, and operators with
IPINFO_APIKEY configured rely on outbound HTTPS. Make the dependency
explicit to:
* Match master's package set rather than relying on a transitive pull
that some future apk dep change could drop.
* Document the runtime TLS requirement at the Dockerfile level instead
of leaving it implicit.
~50 KB image-size cost; the umbrella ca-certificates package adds the
update-ca-certificates CLI on top of the bundle. Per Qodo's review on
PR #800.
The current Dockerfile.alpine pulls FROM php:8-alpine and then `apk
add php-apache2`. The result is two PHP installs side by side: the
docker-library PHP at /usr/local/bin/php (~30 MB, never used by
Apache) and the apk-installed PHP at /usr/bin/php (which mod_php
actually loads).
Pinning a fresh Alpine release and installing the apk packages
directly drops the dead /usr/local/bin/php install entirely.
Expected wins:
- Smaller image (~30 MB less; 2024 baseline was ~120 MB)
- One PHP binary, no $PATH ambiguity
- Cleaner story for any follow-up that touches PHP config
* Initial plan
* Add Docker TAGLINE env customization for modern UI slogan
Agent-Logs-Url: https://github.com/librespeed/speedtest/sessions/e1da6e0e-5194-453d-bffb-961ed782e215
Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>
* Refine TAGLINE replacement and expand E2E coverage
Agent-Logs-Url: https://github.com/librespeed/speedtest/sessions/e1da6e0e-5194-453d-bffb-961ed782e215
Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>
* Fix TAGLINE sed delimiter and add apostrophe tagline E2E test
- Switch TAGLINE sed from '#' to '/' delimiter so html_escape'd
apostrophes (') don't break the sed expression
- Add standalone-apostrophe Docker service with TAGLINE="It'd rather be fast!"
- Add standaloneApostrophe URL (port 18186) to env.js
- Add E2E test asserting the apostrophe tagline renders correctly
Agent-Logs-Url: https://github.com/librespeed/speedtest/sessions/ebe265a8-4b1e-49b5-959a-66133ea0ab3a
Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>
* docker: restore TITLE env handling in entrypoint
* docker: escape TITLE for HTML output
* test(e2e): cover TITLE with umlauts and quotes
---------
Co-authored-by: Stefan Stidl <sti-github@stidl.com>
* ci: make standalone playwright manual and document e2e gating
* docs(test): refine playwright plan with implemented CI strategy
---------
Co-authored-by: Stefan Stidl <stefan.stidl@ffg.at>
* fix: return client IPv6 address via cloudflared
The cloudflared reverse proxy populates the X-Forwarded-For header for origin IPv4 addresses, however origin IPv6 addresses are added in a different header: Cf-Connecting-Ipv6. This updates the getIP.php mechanism to retrieve the value of this header and to prefer it over other client IP headers (in both cases only if the Cf-Connecting-Ipv6 header exists and is not empty).
* fix: Validate and normalise IP addresses from request headers
getClientIp() used HTTP_CF_CONNECTING_IPV6 and other headers verbatim, allowing malformed values to reach ISP lookups and the offline DB.
Add normalizeCandidateIp() helper that trims whitespace, extracts the first comma-separated token, and validates via filter_var(). Require FILTER_FLAG_IPV6 for the CF header and fall through to the next source on failure.
Written with assistance from OpenCode using Claude Opus 4.6.
* Initial plan
* Fix PHP version check to require PHP 8.1.0+ for geoip2.phar
Changed from PHP_MAJOR_VERSION >= 8 to PHP_VERSION_ID >= 80100 to match
the actual requirement of geoip2.phar which needs PHP 8.1.0 or higher.
This prevents HTTP 500 errors on PHP 8.0.x installations.
Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>
* Initial plan
* Fix SQLite database path and add write permission checks
- Changed default SQLite database path from '../../speedtest_telemetry.sql' to '__DIR__/speedtest_telemetry.db' to keep it within the results directory
- Added directory existence and writability checks with helpful error messages
- Added SQLite database files to .gitignore to prevent committing user data
Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>
* Fix indentation to use tabs consistently in telemetry_db.php
Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>
* Remove temporary backup file
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>
* Initial plan
* Add ALT attribute to SpeedTest result image for accessibility
Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>
* Add alt attribute to docker/ui.php for accessibility
Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: sstidl <12804296+sstidl@users.noreply.github.com>