diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..afe87b2 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "env": { + "browser": true, + "es6": true, + "worker": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": 2015, + "sourceType": "script" + }, + "globals": { + "XMLHttpRequest": "readonly", + "Worker": "readonly", + "Blob": "readonly", + "URL": "readonly", + "navigator": "readonly", + "document": "readonly", + "window": "readonly", + "console": "readonly", + "setTimeout": "readonly", + "clearTimeout": "readonly", + "setInterval": "readonly", + "clearInterval": "readonly", + "postMessage": "readonly", + "onmessage": "writable", + "addEventListener": "readonly" + }, + "rules": { + "no-unused-vars": ["warn", { "args": "none" }], + "no-console": "off", + "no-empty": "warn", + "no-undef": "warn", + "no-const-assign": "error" + } +} diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..b023cda --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "github-actions" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" + - package-ecosystem: "docker" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 422ee13..36eb698 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -45,7 +45,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 # Fetch the ipinfo database file using curl if API key is defined - name: Fetch DB from ipinfo.io @@ -94,7 +94,7 @@ jobs: # https://github.com/docker/build-push-action - name: Build and push Docker image id: build-and-push - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v6 with: context: . file: ${{ matrix.dockerfile }} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000..6e242fb --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,31 @@ +# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time. +# +# You can adjust the behavior by modifying this file. +# For more information, see: +# https://github.com/actions/stale +name: Mark stale issues and pull requests + +on: + schedule: + - cron: '32 18 * * *' + +jobs: + stale: + + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + + steps: + - uses: actions/stale@v10 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.' + stale-pr-message: 'This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.' + days-before-stale: 60 + days-before-close: 7 + close-issue-message: 'This issue was automatically closed due to inactivity.' + close-pr-message: 'This pull request was automatically closed due to inactivity.' + stale-issue-label: 'no-issue-activity' + stale-pr-label: 'no-pr-activity' diff --git a/.gitignore b/.gitignore index b07ea8a..7c7fb63 100755 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ results/idObfuscation_salt.php backend/getIP_serverLocation.php db-dir/ .vscode/ +node_modules/ +package-lock.json diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..fb8c426 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,14 @@ +node_modules/ +backend/ +results/ +docker/ +.git/ +*.php +*.md +*.sql +*.mmdb +*.phar +*.ttf +*.ico +*.png +*.gif diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..3149967 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,12 @@ +{ + "printWidth": 120, + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": false, + "trailingComma": "none", + "bracketSpacing": true, + "arrowParens": "avoid", + "endOfLine": "lf", + "htmlWhitespaceSensitivity": "ignore" +} diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000..66e4eb4 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,122 @@ +# Development Guide + +This document describes how to use the package manager (npm) for development tasks. + +## Prerequisites + +- Node.js 14.0.0 or higher +- npm (comes with Node.js) + +## Getting Started + +Install development dependencies: + +```bash +npm install +``` + +## Available Scripts + +### Linting + +Check code for potential issues: + +```bash +npm run lint +``` + +Automatically fix linting issues where possible: + +```bash +npm run lint:fix +``` + +### Code Formatting + +Check code formatting (JavaScript files only): + +```bash +npm run format:check +``` + +Format JavaScript files: + +```bash +npm run format +``` + +> **Note**: The existing codebase uses its original formatting style. Prettier and ESLint are provided as optional tools for new code or improvements. + +### Validation + +Run all checks (formatting and linting): + +```bash +npm run validate +``` + +### Testing + +Currently, there are no automated tests configured: + +```bash +npm run test +``` + +### Docker + +Build Docker images: + +```bash +npm run docker:build # Standard Debian-based image +npm run docker:build-alpine # Alpine-based image +``` + +## Development Tools + +The package manager setup includes: + +- **ESLint**: JavaScript linting tool to catch common errors +- **Prettier**: Code formatting tool to maintain consistent style + +These tools are configured but non-intrusive to the existing codebase. + +## Project Structure + +``` +. +├── speedtest.js # Main speedtest library +├── speedtest_worker.js # Web Worker for speed testing +├── index.html # Default UI +├── backend/ # PHP backend files +├── examples/ # Example implementations +├── results/ # Results/telemetry handling +├── docker/ # Docker-related files +└── package.json # npm package configuration +``` + +## Why Use a Package Manager? + +The package manager provides several benefits: + +1. **Standardized tooling**: Common commands across different environments +2. **Development dependencies**: Easy installation of linting and formatting tools +3. **Project metadata**: Version, description, and licensing information +4. **Future extensibility**: Foundation for adding build tools, tests, or bundlers if needed +5. **npm distribution**: Makes the library easy to use in other Node.js projects + +## Contributing + +When making changes: + +1. Run `npm run lint` to check for potential issues +2. Consider running `npm run format` on new files for consistency +3. Test your changes manually in a browser +4. For PHP backend changes, test with the appropriate server setup + +## Notes + +- The core library has **no runtime dependencies** - it's pure vanilla JavaScript +- Development dependencies (ESLint, Prettier) are only needed for development +- The library can still be used standalone without npm (just include the JS files) +- npm setup is completely optional and doesn't change how the library is deployed diff --git a/Dockerfile b/Dockerfile index e4ea1c8..365f1b6 100755 --- a/Dockerfile +++ b/Dockerfile @@ -3,13 +3,12 @@ FROM php:8-apache # use docker-php-extension-installer for automatically get the right packages installed ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ - -# Install extensions -RUN install-php-extensions iconv gd pdo pdo_mysql pdo_pgsql pgsql - -RUN rm -f /usr/src/php.tar.xz /usr/src/php.tar.xz.asc \ - && apt autoremove -y \ - && rm -rf /var/lib/apt/lists/* +# Install extensions and cleanup in a single layer to reduce image size +RUN install-php-extensions iconv gd pdo pdo_mysql pdo_pgsql pgsql \ + && rm -f /usr/src/php.tar.xz /usr/src/php.tar.xz.asc \ + && apt-get autoremove -y \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* # Prepare files and folders RUN mkdir -p /speedtest/ @@ -40,6 +39,19 @@ ENV WEBPORT=8080 # https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop STOPSIGNAL SIGWINCH +# Add labels for better metadata +LABEL org.opencontainers.image.title="LibreSpeed" +LABEL org.opencontainers.image.description="A Free and Open Source speed test that you can host on your server(s)" +LABEL org.opencontainers.image.vendor="LibreSpeed" +LABEL org.opencontainers.image.url="https://github.com/librespeed/speedtest" +LABEL org.opencontainers.image.source="https://github.com/librespeed/speedtest" +LABEL org.opencontainers.image.documentation="https://github.com/librespeed/speedtest/blob/master/doc_docker.md" +LABEL org.opencontainers.image.licenses="LGPL-3.0-or-later" + +# Add health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ + CMD curl -f http://localhost:${WEBPORT}/ || exit 1 + # Final touches EXPOSE ${WEBPORT} CMD ["bash", "/entrypoint.sh"] diff --git a/Dockerfile.alpine b/Dockerfile.alpine index 39b2ce3..1026d95 100755 --- a/Dockerfile.alpine +++ b/Dockerfile.alpine @@ -15,13 +15,9 @@ RUN apk add --quiet --no-cache \ php-session \ php-sqlite3 -# use docker-php-extension-installer for automatically get the right packages installed -ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ - - - -# Install extensions -RUN install-php-extensions iconv gd pdo pdo_mysql pdo_pgsql pgsql +# Note: PHP extensions are provided via Alpine `php-*` packages above. +# The docker-php-extension-installer is redundant when using those packages, +# so it's intentionally removed to simplify the image. RUN ln -sf /dev/stdout /var/log/apache2/access.log && \ ln -sf /dev/stderr /var/log/apache2/error.log @@ -55,6 +51,19 @@ ENV WEBPORT=8080 # https://httpd.apache.org/docs/2.4/stopping.html#gracefulstop STOPSIGNAL SIGWINCH +# Add labels for better metadata +LABEL org.opencontainers.image.title="LibreSpeed" +LABEL org.opencontainers.image.description="A Free and Open Source speed test that you can host on your server(s)" +LABEL org.opencontainers.image.vendor="LibreSpeed" +LABEL org.opencontainers.image.url="https://github.com/librespeed/speedtest" +LABEL org.opencontainers.image.source="https://github.com/librespeed/speedtest" +LABEL org.opencontainers.image.documentation="https://github.com/librespeed/speedtest/blob/master/doc_docker.md" +LABEL org.opencontainers.image.licenses="LGPL-3.0-or-later" + +# Add health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:${WEBPORT}/ || exit 1 + WORKDIR /var/www/html # Final touches diff --git a/README.md b/README.md index 184f377..4ae9410 100755 --- a/README.md +++ b/README.md @@ -59,6 +59,10 @@ A template to build an Android client for your LibreSpeed installation is availa A command line client is available [here](https://github.com/librespeed/speedtest-cli). +## Development + +If you want to contribute or develop with LibreSpeed, see [DEVELOPMENT.md](DEVELOPMENT.md) for information about using npm for development tasks, linting, and formatting. + ## Docker 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. diff --git a/docker/test/test-script.sh b/docker/test/test-script.sh index 1e8661b..4bf47df 100644 --- a/docker/test/test-script.sh +++ b/docker/test/test-script.sh @@ -9,7 +9,7 @@ if ! apk add w3m; then exit 1 fi -echo sleeping a little to get things setteled... +echo sleeping a little to get things settled... sleep 15 for db in sqlite pg mysql; do diff --git a/package.json b/package.json new file mode 100644 index 0000000..5f088ce --- /dev/null +++ b/package.json @@ -0,0 +1,55 @@ +{ + "name": "librespeed-speedtest", + "version": "5.4.1", + "description": "LibreSpeed - A Free and Open Source speed test that you can host on your server(s)", + "main": "speedtest.js", + "scripts": { + "test": "echo \"No automated tests configured yet\" && exit 0", + "lint": "eslint speedtest.js speedtest_worker.js", + "lint:fix": "eslint --fix speedtest.js speedtest_worker.js", + "format": "prettier --write \"*.js\"", + "format:check": "prettier --check \"*.js\"", + "validate": "npm run format:check && npm run lint", + "docker:build": "docker build -t librespeed-speedtest .", + "docker:build-alpine": "docker build -t librespeed-speedtest:alpine -f Dockerfile.alpine ." + }, + "repository": { + "type": "git", + "url": "git+https://github.com/librespeed/speedtest.git" + }, + "keywords": [ + "speedtest", + "speed-test", + "internet-speed", + "bandwidth", + "network", + "performance", + "librespeed", + "download", + "upload", + "ping", + "latency" + ], + "author": "Federico Dossena", + "license": "LGPL-3.0-or-later", + "bugs": { + "url": "https://github.com/librespeed/speedtest/issues" + }, + "homepage": "https://github.com/librespeed/speedtest#readme", + "devDependencies": { + "eslint": "^8.57.0", + "prettier": "^3.1.1" + }, + "files": [ + "speedtest.js", + "speedtest_worker.js", + "index.html", + "favicon.ico", + "backend/", + "examples/", + "results/" + ], + "engines": { + "node": ">=14.0.0" + } +} diff --git a/speedtest.js b/speedtest.js index a272bb1..936903b 100755 --- a/speedtest.js +++ b/speedtest.js @@ -330,7 +330,7 @@ Speedtest.prototype = { console.error("Speedtest onupdate event threw exception: " + e); } if (data.testState >= 4) { - clearInterval(this.updater); + clearInterval(this.updater); this._state = 4; try { if (this.onend) this.onend(data.testState == 5);