Docker更改为中文,并且可以使用TZ环境变量

This commit is contained in:
Alan Xiong 2024-04-15 08:18:29 +08:00
parent 80cf39987a
commit 0b64f64b2c
13 changed files with 333 additions and 332 deletions

5
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,5 @@
{
"githubPullRequests.ignoredPullRequestBranches": [
"master"
]
}

113
README.md
View file

@ -2,83 +2,74 @@
# LibreSpeed
No Flash, No Java, No Websocket, No Bullshit.
无需Flash、Java、WebSocket没有废话。
This is a very lightweight speed test implemented in Javascript, using XMLHttpRequest and Web Workers.
这是一个用Javascript实现的非常轻量级的网速测试工具使用XMLHttpRequest和Web Workers。
## Try it
[Take a speed test](https://librespeed.org)
## 试试吧
[进行网速测试](https://librespeed.org)
## Compatibility
All modern browsers are supported: IE11, latest Edge, latest Chrome, latest Firefox, latest Safari.
Works with mobile versions too.
## 兼容性
支持所有现代浏览器IE11、最新版Edge、最新版Chrome、最新版Firefox、最新版Safari。
同样适用于移动版本。
## Features
* Download
* Upload
* Ping
* Jitter
* IP Address, ISP, distance from server (optional)
* Telemetry (optional)
* Results sharing (optional)
* Multiple Points of Test (optional)
## 特性
* 下载速度
* 上传速度
* 延迟(Ping
* 抖动(Jitter
* IP地址、ISP、与服务器的距离可选
* 遥测数据(可选)
* 结果分享(可选)
* 多点测试(可选)
![Screenrecording of a running Speedtest](https://speedtest.fdossena.com/mpot_v6.gif)
![正在进行的Speedtest屏幕录像](https://speedtest.fdossena.com/mpot_v6.gif)
## 服务器要求
* 一个配置合理的快速Web服务器支持Apache 2也支持nginx、IIS
* PHP 5.4(也支持其他后端)
* MySQL数据库来存储测试结果可选也支持Microsoft SQL Server、PostgreSQL和SQLite
* 一个快速的互联网连接
## Server requirements
* A reasonably fast web server with Apache 2 (nginx, IIS also supported)
* PHP 5.4 or newer (other backends also available)
* MySQL database to store test results (optional, Microsoft SQL Server, PostgreSQL and SQLite also supported)
* A fast! internet connection
## 安装
假设你已经安装了PHP安装步骤相当简单。
我在QNAP上设置了这个。
以此次为例,我在网络共享区域使用了一个名为**speedtest**的文件夹。
## 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. 选择example-xxx.html文件中的一个作为你speedtest文件夹中的新index.html。我使用的是example-singleServer-full.html
2. 将speedtest.js、speedtest_worker.js和favicon.ico添加到你的speedtest文件夹中。
3. 将整个backend文件夹下载到speedtest/backend中。
4. 将整个results文件夹下载到speedtest/results中。
5. 确保你的权限允许执行755
6. 访问YOURSITE/speedtest/index.html就这样
1. Choose one of the example-xxx.html files in `examples` folder as your index.html if the default index.html does not fit.
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!
### 安装视频
这里有一个更深入的安装视频:
* [Ubuntu Server 19.04快速开始安装指南](https://fdossena.com/?p=speedtest/quickstart_v5_ubuntu.frag)
### 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
A template to build an Android client for your LibreSpeed installation is available [here](https://github.com/librespeed/speedtest-android).
## CLI client
A command line client is available [here](https://github.com/librespeed/speedtest-cli).
## Android应用
为你的LibreSpeed安装构建Android客户端的模板可以在[这里](https://github.com/librespeed/speedtest-android)找到。
## 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.
Docker镜像可以在[GitHub](https://github.com/librespeed/speedtest/pkgs/container/speedtest)上找到,查看我们的[docker文档](doc_docker.md)了解更多信息。
## 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).
## Go后端
一个Go实现版本可以在[`speedtest-go`](https://github.com/librespeed/speedtest-go)仓库中找到,由[Maddie Zhan](https://github.com/maddie)维护。
## Node.js backend
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.
## Node.js后端
`node`分支中有一个部分实现的Node.js版本由[dunklesToast](https://github.com/dunklesToast)开发。目前不推荐使用。
## Donate
[![Donate with Liberapay](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/fdossena/donate)
[Donate with PayPal](https://www.paypal.me/sineisochronic)
## 捐赠
[![通过Liberapay捐赠](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/fdossena/donate)
[通过PayPal捐赠](https://www.paypal.me/sineisochronic)
## License
Copyright (C) 2016-2022 Federico Dossena
## 许可证
版权所有 (C) 2016-2022 Federico Dossena
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
这个程序是自由软件你可以在GNU Lesser General Public License的条款下重新分发和/或修改它该许可证由自由软件基金会发布要么是许可证的第3版或者根据你的选择任何后续版本。
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
这个程序希望它是有用的,
但没有任何保证甚至没有暗示的保证MERCHANTABILITY或特定目的的适用性。详情请参见GNU通用公共许可证。
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/lgpl>.
你应该已经收到了GNU Lesser General Public License的副本
和这个程序一起。如果没有,参见<https://www.gnu.org/licenses/lgpl>

9
doc.md
View file

@ -109,7 +109,8 @@ 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, the default page uses telemetry and results sharing. If you want another index page, 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`.
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.
@ -118,7 +119,7 @@ Details about the examples and how to make custom UIs will be discussed later. I
#### Privacy
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.
Default `index.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.__
`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.__
### Multiple servers, PHP
The speed test can automatically choose between multiple test points and use the one with the lowest ping in a list.
@ -239,11 +240,11 @@ __Single server:__
* `example-singleServer-customSettings.html`: Same as `example-singleServer-pretty.html` but configures the test so that it only performs download and upload tests, and with a fixed length instead of automatic
* `example-singleServer-gauges.html`: The most sophisticated example, with the same functionality as `example-singleServer-pretty.html` but adds gauges. This is also a good starting point, but the gauges may slow down underpowered devices
* `example-singleServer-chart.html`: Shows how to use the test with the Chart.js library
* default `index.html`: The most complete example. Based on `example-singleServer-gauges.html`, also enables telemetry and results sharing
* `example-singleServer-full.html`: The most complete example. Based on `example-singleServer-gauges.html`, also enables telemetry and results sharing
__Multiple servers:__
* `example-multipleServers-pretty.html`: Same as `example-singleServer-pretty.html` but with multiple test points. Server selection is fully automatic
* `example-multipleServers-full.html`: Same as default `index.html` but with multiple test points. Server selection is automatic but the server can be changed afterwards by the user
* `example-multipleServers-full.html`: Same as `example-singleServer-full.html` but with multiple test points. Server selection is automatic but the server can be changed afterwards by the user
### Initialization
To use the speed test in your page, first you need to load it:

View file

@ -1,24 +1,23 @@
A docker version of LibreSpeed is available here: [GitHub Packages](https://github.com/librespeed/speedtest/pkgs/container/speedtest)
LibreSpeed的Docker版本可以在这里找到[GitHub Packages](https://github.com/librespeed/speedtest/pkgs/container/speedtest)
## Downloading docker image
To download LibreSpeed from the docker repo, use this command:
## 下载 Docker 镜像
要从 Docker 仓库下载 LibreSpeed请使用以下命令
```
docker pull ghcr.io/librespeed/speedtest
docker pull ghcr.io/kumakaiha/speedtest
```
You will now have a new docker image called `librespeed/speedtest`.
现在您将拥有一个名为 `kumakaiha/speedtest` 的新 Docker 镜像。
## Docker Compose
To start the container using [docker compose](https://docs.docker.com/compose/) the following configuration can be used:
要使用 [docker compose](https://docs.docker.com/compose/) 启动容器,可以使用以下配置:
```yml
version: '3.7'
services:
speedtest:
container_name: speedtest
image: ghcr.io/librespeed/speedtest:latest
image: ghcr.io/kumakaiha/speedtest:latest
restart: always
environment:
MODE: standalone
@ -35,72 +34,73 @@ services:
- "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`.
## 独立模式
如果您想在单个服务器上安装 LibreSpeed则需要将其配置为独立模式。为此请将 `MODE` 环境变量设置为 `standalone`
The test can be accessed on port 80.
测试可以通过端口 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. 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.
* __`EMAIL`__: Email address for GDPR requests. Must be specified when telemetry is enabled.
* __`IPINFO_APIKEY`__: API key for ipinfo.io. Optional, but required if you expect to serve a large number of tests
* __`DISABLE_IPINFO`__: If set to true, ISP info and distance will not be fetched from ipinfo.io. Default: value: `false`
* __`DISTANCE`__: When `DISABLE_IPINFO` is set to false, this specifies how the distance from the server is measured. Can be either `km` for kilometers, `mi` for miles, or an empty string to disable distance measurement. Default value: `km`
* __`WEBPORT`__: Allows choosing a custom port for the included web server. Default value: `80`. Note that you will have to expose it through docker with the -p argument
以下是在此模式下可用的其他环境变量列表:
* __`TITLE`__: 您的速度测试标题。默认值:`LibreSpeed`
* __`TELEMETRY`__: 是否启用遥测。如果启用,您可能希望持久保存数据。请参见下文。默认值:`false`
* __`ENABLE_ID_OBFUSCATION`__: 当启用遥测并设置为 true 时,测试 ID 将被模糊化,以避免暴露数据库内部的顺序 ID。默认值`false`
* __`REDACT_IP_ADDRESSES`__: 当启用遥测并设置为 true 时IP 地址和主机名将从收集的遥测数据中删除,以提高隐私性。默认值:`false`
* __`PASSWORD`__: 访问统计页面的密码。如果未设置,统计页面将不允许访问。
* __`EMAIL`__: GDPR 请求的电子邮件地址。在启用遥测时必须指定。
* __`IPINFO_APIKEY`__: ipinfo.io 的 API 密钥。可选,但如果您希望提供大量测试,则需要。
* __`DISABLE_IPINFO`__: 如果设置为 true则不会从 ipinfo.io 获取 ISP 信息和距离。默认值:`false`
* __`DISTANCE`__: 当 `DISABLE_IPINFO` 设置为 false 时,指定从服务器测量的距离方式。可以是 `km` 表示千米,`mi` 表示英里,或空字符串表示禁用距离测量。默认值:`km`
* __`WEBPORT`__: 允许选择包含的 Web 服务器的自定义端口。默认值:`80`。请注意,您将需要通过 -p 参数在 Docker 中公开它。
* __`TZ`__: 设定容器时区,并使得遥测数据符合当地时间。默认值:`Asia/Shanghai`。注意仅在x86设备使用SQLITE的Docker环境中测试。
If telemetry is enabled, a stats page will be available at `http://your.server/results/stats.php`, but a password must be specified.
如果启用了遥测,将在 `http://your.server/results/stats.php` 上提供统计页面,但必须指定密码。
### Persist sqlite database
### 持久化 sqlite 数据库
Default DB driver is sqlite. The DB file is written to `/database/db.sql`.
默认的数据库驱动程序是 sqlite。数据库文件写入 `/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`.
因此,如果希望数据在镜像更新后保持不变,必须通过 `-v $PWD/db-dir:/database` 挂载卷。
###### Example
This command starts LibreSpeed in standalone mode, with the default settings, on port 80:
###### 示例
此命令在端口 80 上使用默认设置以独立模式启动 LibreSpeed
```
docker run -e MODE=standalone -p 80:80 -it ghcr.io/librespeed/speedtest
docker run -e MODE=standalone -p 80:80 -it ghcr.io/kumakaiha/speedtest
```
This command starts LibreSpeed in standalone mode, with telemetry, ID obfuscation and a stats password, on port 86:
此命令在端口 86 上使用独立模式启动 LibreSpeed包括遥测、ID 模糊化和统计密码:
```
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
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/kumakaiha/speedtest
```
## Multiple Points of Test
For multiple servers, you need to set up 1+ LibreSpeed backends, and 1 LibreSpeed frontend.
## 多个测试点
对于多个服务器,您需要设置 1 个或多个 LibreSpeed 后端和 1 个 LibreSpeed 前端。
### Backend mode
In backend mode, LibreSpeed provides only a test point with no UI. To do this, set the `MODE` environment variable to `backend`.
### 后端模式
在后端模式下LibreSpeed 仅提供一个测试点,没有用户界面。为此,请将 `MODE` 环境变量设置为 `backend`
The following backend files can be accessed on port 80: `garbage.php`, `empty.php`, `getIP.php`
可以通过端口 80 访问以下后端文件:`garbage.php`、`empty.php`、`getIP.php`
Here's a list of additional environment variables available in this mode:
* __`IPINFO_APIKEY`__: API key for ipinfo.io. Optional, but required if you expect to serve a large number of tests
以下是在此模式下可用的其他环境变量列表:
* __`IPINFO_APIKEY`__: ipinfo.io 的 API 密钥。可选,但如果您希望提供大量测试,则需要。
###### 示例:
此命令在端口 80 上使用默认设置以后端模式启动 LibreSpeed
###### Example:
This command starts LibreSpeed in backend mode, with the default settings, on port 80:
```
docker run -e MODE=backend -p 80:80 -it ghcr.io/librespeed/speedtest
```
### Frontend mode
In frontend mode, LibreSpeed serves clients the Web UI and a list of servers. To do this:
* Set the `MODE` environment variable to `frontend`
* Create a servers.json file with your test points. The syntax is the following:
### 前端模式
在前端模式下LibreSpeed 为客户端提供 Web 用户界面和服务器列表。为此:
* `MODE` 环境变量设置为 `frontend`
* 使用您的测试点创建一个 servers.json 文件。语法如下:
```
[
{
"name": "Friendly name for Server 1",
"name": "服务器 1 的友好名称",
"server" :"//server1.mydomain.com/",
"dlURL" :"garbage.php",
"ulURL" :"empty.php",
@ -108,41 +108,35 @@ In frontend mode, LibreSpeed serves clients the Web UI and a list of servers. To
"getIpURL" :"getIP.php"
},
{
"name": "Friendly name for Server 2",
"name": "服务器 2 的友好名称",
"server" :"https://server2.mydomain.com/",
"dlURL" :"garbage.php",
"ulURL" :"empty.php",
"pingURL" :"empty.php",
"getIpURL" :"getIP.php"
},
...more servers...
...更多服务器...
]
```
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)
注意:如果服务器仅支持 HTTP 或 HTTPS请在服务器字段中指定协议。如果两者都支持请使用 `//`
* 将此文件挂载到容器中的 `/servers.json`(在本文件末尾有示例)
The test can be accessed on port 80.
测试可以通过端口 80 访问。
Here's a list of additional environment variables available in this mode:
* __`TITLE`__: Title of your speedtest. Default value: `LibreSpeed`
* __`TELEMETRY`__: Whether to enable telemetry or not. 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.
* __`EMAIL`__: Email address for GDPR requests. Must be specified when telemetry is enabled.
* __`DISABLE_IPINFO`__: If set to true, ISP info and distance will not be fetched from ipinfo.io. Default: value: `false`
* __`DISTANCE`__: When `DISABLE_IPINFO` is set to false, this specifies how the distance from the server is measured. Can be either `km` for kilometers, `mi` for miles, or an empty string to disable distance measurement. Default value: `km`
* __`WEBPORT`__: Allows choosing a custom port for the included web server. Default value: `80`
以下是在此模式下可用的其他环境变量列表:
* __`TITLE`__: 您的速度测试标题。默认值:`LibreSpeed`
* __`TELEMETRY`__: 是否启用遥测。默认值:`false`
* __`ENABLE_ID_OBFUSCATION`__: 当启用遥测并设置为 true 时,测试 ID 将被模糊化,以避免暴露数据库内部的顺序 ID。默认值`false`
* __`REDACT_IP_ADDRESSES`__: 当启用遥测并设置为 true 时IP 地址和主机名将从收集的遥测数据中删除,以提高隐私性。默认值:`false`
* __`PASSWORD`__: 访问统计页面的密码。如果未设置,统计页面将不允许访问。
* __`EMAIL`__: GDPR 请求的电子邮件地址。在启用遥测时必须指定。
* __`DISABLE_IPINFO`__: 如果设置为 true则不会从 ipinfo.io 获取 ISP 信息和距离。默认值:`false`
* __`DISTANCE`__: 当 `DISABLE_IPINFO` 设置为 false 时,指定从服务器测量的距禂方式。可以是 `km` 表示千米,`mi` 表示英里,或空字符串表示禁用距离测量。默认值:`km`
* __`WEBPORT`__: 允许选择包含的 Web 服务器的自定义端口。默认值:`80`
###### 示例
此命令在前端模式下启动 LibreSpeed使用给定的 `servers.json` 文件以及遥测、ID 模糊化和统计密码:
###### 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 ghcr.io/librespeed/speedtest
```
### Dual mode
In dual mode, LibreSpeed operates as a standalone server that can also connect to other test points.
To do this:
* Set the `MODE` environment variable to `dual`
* Follow the `servers.json` instructions for the frontend mode
* The first server entry should be the local server, using the server endpoint address that a client can access.
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/kumakaiha/speedtest
```

View file

@ -1,48 +1,39 @@
#!/bin/bash
set -e
set -x
# Cleanup
rm -rf /var/www/html/*
# Copy frontend files
cp /speedtest/*.js /var/www/html/
# Copy favicon
cp /speedtest/favicon.ico /var/www/html/
# Set up backend side for standlone modes
if [[ "$MODE" == "standalone" || "$MODE" == "dual" ]]; then
if [ "$MODE" == "standalone" ]; then
cp -r /speedtest/backend/ /var/www/html/backend
if [ ! -z "$IPINFO_APIKEY" ]; then
sed -i s/\$IPINFO_APIKEY\ =\ \'\'/\$IPINFO_APIKEY\ =\ \'$IPINFO_APIKEY\'/g /var/www/html/backend/getIP_ipInfo_apikey.php
fi
fi
if [ "$MODE" == "backend" ]; then
cp -r /speedtest/backend/* /var/www/html
if [ ! -z "$IPINFO_APIKEY" ]; then
sed -i s/\$IPINFO_APIKEY\ =\ \'\'/\$IPINFO_APIKEY\ =\ \'$IPINFO_APIKEY\'/g /var/www/html/getIP_ipInfo_apikey.php
fi
fi
# Set up index.php for frontend-only or standalone modes
if [[ "$MODE" == "frontend" || "$MODE" == "dual" ]]; then
if [ "$MODE" == "frontend" ]; then
cp /speedtest/frontend.php /var/www/html/index.php
elif [ "$MODE" == "standalone" ]; then
cp /speedtest/standalone.php /var/www/html/index.php
fi
# Apply Telemetry settings when running in standalone or frontend mode and telemetry is enabled
if [[ "$TELEMETRY" == "true" && ( "$MODE" == "frontend" || "$MODE" == "standalone" || "$MODE" == "dual" ) ]]; then
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
fi
if [ "$DB_TYPE" == "mysql" ]; then
sed -i 's/$db_type = '\''.*'\''/$db_type = '\'$DB_TYPE\''/g' /var/www/html/results/telemetry_settings.php
sed -i 's/$MySql_username = '\''.*'\''/$MySql_username = '\'$DB_USERNAME\''/g' /var/www/html/results/telemetry_settings.php
@ -61,31 +52,24 @@ if [[ "$TELEMETRY" == "true" && ( "$MODE" == "frontend" || "$MODE" == "standalon
else
sed -i s/\$db_type\ =\ \'.*\'/\$db_type\ =\ \'sqlite\'\/g /var/www/html/results/telemetry_settings.php
fi
sed -i s/\$Sqlite_db_file\ =\ \'.*\'/\$Sqlite_db_file=\'\\\/database\\\/db.sql\'/g /var/www/html/results/telemetry_settings.php
sed -i s/\$stats_password\ =\ \'.*\'/\$stats_password\ =\ \'$PASSWORD\'/g /var/www/html/results/telemetry_settings.php
if [ "$ENABLE_ID_OBFUSCATION" == "true" ]; then
sed -i s/\$enable_id_obfuscation\ =\ .*\;/\$enable_id_obfuscation\ =\ true\;/g /var/www/html/results/telemetry_settings.php
fi
if [ "$REDACT_IP_ADDRESSES" == "true" ]; then
sed -i s/\$redact_ip_addresses\ =\ .*\;/\$redact_ip_addresses\ =\ true\;/g /var/www/html/results/telemetry_settings.php
fi
mkdir -p /database/
chown www-data /database/
fi
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
fi
echo "Done, Starting APACHE"
# This runs apache
apache2-foreground

View file

@ -182,6 +182,14 @@ function initUI(){
I("jitText").textContent="";
I("ip").textContent="";
}
function copyResultsURL() {
var resultsURL = document.getElementById('resultsURL');
resultsURL.style.display = 'block'; // 显示文本框
resultsURL.select(); // 选中文本
document.execCommand('copy'); // 复制文本
resultsURL.style.display = 'none'; // 隐藏文本框
alert('结果链接已复制');
}
</script>
<style type="text/css">
html,body{
@ -238,10 +246,10 @@ function initUI(){
color:#FFFFFF;
}
#startStopBtn:before{
content:"Start";
content:"开始测速";
}
#startStopBtn.running:before{
content:"Abort";
content:"终止";
}
#serverArea{
margin-top:1em;
@ -252,7 +260,7 @@ function initUI(){
}
#test{
margin-top:2em;
margin-bottom:12em;
margin-bottom:10em;
}
div.testArea{
display:inline-block;
@ -378,17 +386,18 @@ function initUI(){
}
}
</style>
<title><?= getenv('TITLE') ?: 'LibreSpeed Example' ?></title>
<title><?= getenv('TITLE') ?: '服务器测速' ?></title>
</head>
<body onload="initServers()">
<h1><?= getenv('TITLE') ?: 'LibreSpeed Example' ?></h1>
<h1><?= getenv('TITLE') ?: '服务器点对点测速' ?></h1>
<div id="loading" class="visible">
<p id="message"><span class="loadCircle"></span>Selecting a server...</p>
<p id="message"><span class="loadCircle"></span>选择一个服务器...</p>
</div>
<div id="testWrapper" class="hidden">
<div id="startStopBtn" onclick="startStop()"></div>
<?php if(getenv("TELEMETRY")=="true"){ ?>
<a class="privacy" href="#" onclick="I('privacyPolicy').style.display=''">Privacy</a>
<a class="privacy" href="#" onclick="window.location.href = window.location.origin + '/results/stats.php';">进入统计数据页面</a>
<a class="privacy" href="#" onclick="I('privacyPolicy').style.display=''">隐私政策</a>
<?php } ?>
<div id="serverArea">
Server: <select id="server" onchange="s.setSelectedServer(SPEEDTEST_SERVERS[this.value])"></select>
@ -396,25 +405,25 @@ function initUI(){
<div id="test">
<div class="testGroup">
<div class="testArea2">
<div class="testName">Ping</div>
<div class="testName">延迟</div>
<div id="pingText" class="meterText" style="color:#AA6060"></div>
<div class="unit">ms</div>
</div>
<div class="testArea2">
<div class="testName">Jitter</div>
<div class="testName">抖动</div>
<div id="jitText" class="meterText" style="color:#AA6060"></div>
<div class="unit">ms</div>
</div>
</div>
<div class="testGroup">
<div class="testArea">
<div class="testName">Download</div>
<div class="testName">下载</div>
<canvas id="dlMeter" class="meter"></canvas>
<div id="dlText" class="meterText"></div>
<div class="unit">Mbit/s</div>
</div>
<div class="testArea">
<div class="testName">Upload</div>
<div class="testName">上传</div>
<canvas id="ulMeter" class="meter"></canvas>
<div id="ulText" class="meterText"></div>
<div class="unit">Mbit/s</div>
@ -424,51 +433,51 @@ function initUI(){
<span id="ip"></span>
</div>
<div id="shareArea" style="display:none">
<h3>Share results</h3>
<p>Test ID: <span id="testId"></span></p>
<input type="text" value="" id="resultsURL" readonly="readonly" onclick="this.select();this.focus();this.select();document.execCommand('copy');alert('Link copied')"/>
<img src="" id="resultsImg" />
<h3>被共享的测速结果</h3>
<p>测试 ID: <span id="testId"></span></p>
<input type="text" value="" id="resultsURL" readonly="readonly" style="display: none;" />
<img src="" id="resultsImg" onclick="copyResultsURL()" />
</div>
</div>
<a href="https://github.com/librespeed/speedtest">Source code</a>
由此获取本站 <a href="https://github.com/KUMAKAIHA/speedtest_chinese">源代码</a>
</div>
<div id="privacyPolicy" style="display:none">
<h2>Privacy Policy</h2>
<p>This HTML5 speed test server is configured with telemetry enabled.</p>
<h4>What data we collect</h4>
<h2>隐私政策</h2>
<p>此测速服务器已配置为启用遥测。</p>
<h4>我们收集哪些数据</h4>
<p>
At the end of the test, the following data is collected and stored:
在测试结束时,将收集并存储以下数据:
<ul>
<li>Test ID</li>
<li>Time of testing</li>
<li>Test results (download and upload speed, ping and jitter)</li>
<li>IP address</li>
<li>ISP information</li>
<li>Approximate location (inferred from IP address, not GPS)</li>
<li>User agent and browser locale</li>
<li>Test log (contains no personal information)</li>
<li>测试 ID</li>
<li>测试时间</li>
<li>测试结果下载速度、上传速度、ping 和抖动)</li>
<li>IP 地址</li>
<li>ISP 信息</li>
<li>大致位置(从 IP 地址推断,而非 GPS</li>
<li>用户代理和浏览器区域设置</li>
<li>测试日志(不包含个人信息)</li>
</ul>
</p>
<h4>How we use the data</h4>
<h4>我们如何使用数据</h4>
<p>
Data collected through this service is used to:
通过此服务收集的数据用于:
<ul>
<li>Allow sharing of test results (sharable image for forums, etc.)</li>
<li>To improve the service offered to you (for instance, to detect problems on our side)</li>
<li>允许分享测试结果(适用于论坛等的可共享图像)</li>
<li>改进为您提供的服务(例如,检测我们这一侧的问题)</li>
</ul>
No personal information is disclosed to third parties.
不会向第三方披露个人信息。
</p>
<h4>Your consent</h4>
<h4>您的同意</h4>
<p>
By starting the test, you consent to the terms of this privacy policy.
通过开始测试,您同意本隐私政策条款。
</p>
<h4>Data removal</h4>
<h4>数据删除</h4>
<p>
If you want to have your information deleted, you need to provide either the ID of the test or your IP address. This is the only way to identify your data, without this information we won't be able to comply with your request.<br/><br/>
Contact this email address for all deletion requests: <a href="mailto:<?=getenv("EMAIL") ?>"><?=getenv("EMAIL") ?></a>.
如果您希望删除您的信息,您需要提供测试 ID 或您的 IP 地址。这是唯一识别您数据的方式,没有这些信息,我们将无法满足您的请求。<br/><br/>
请通过以下电子邮件地址联系以获取所有删除请求: <a href="mailto:<?=getenv("EMAIL") ?>"><?=getenv("EMAIL") ?></a>
</p>
<br/><br/>
<a class="privacy" href="#" onclick="I('privacyPolicy').style.display='none'">Close</a><br/>
<a class="privacy" href="#" onclick="I('privacyPolicy').style.display='none'">关闭</a><br/>
</div>
</body>
</html>

View file

@ -132,6 +132,14 @@ function initUI(){
I("jitText").textContent="";
I("ip").textContent="";
}
function copyResultsURL() {
var resultsURL = document.getElementById('resultsURL');
resultsURL.style.display = 'block'; // 显示文本框
resultsURL.select(); // 选中文本
document.execCommand('copy'); // 复制文本
resultsURL.style.display = 'none'; // 隐藏文本框
alert('结果链接已复制');
}
</script>
<style type="text/css">
html,body{
@ -169,14 +177,14 @@ function initUI(){
color:#FFFFFF;
}
#startStopBtn:before{
content:"Start";
content:"开始测速";
}
#startStopBtn.running:before{
content:"Abort";
content:"终止";
}
#test{
margin-top:2em;
margin-bottom:12em;
margin-bottom:10em;
}
div.testArea{
display:inline-block;
@ -276,37 +284,38 @@ function initUI(){
}
}
</style>
<title><?= getenv('TITLE') ?: 'LibreSpeed Example' ?></title>
<title><?= getenv('TITLE') ?: '服务器测速' ?></title>
</head>
<body>
<h1><?= getenv('TITLE') ?: 'LibreSpeed Example' ?></h1>
<h1><?= getenv('TITLE') ?: '服务器点对点测速' ?></h1>
<div id="testWrapper">
<div id="startStopBtn" onclick="startStop()"></div><br/>
<?php if(getenv("TELEMETRY")=="true"){ ?>
<a class="privacy" href="#" onclick="I('privacyPolicy').style.display=''">Privacy</a>
<a class="privacy" href="#" onclick="window.location.href = window.location.origin + '/results/stats.php';">进入统计数据页面</a>
<a class="privacy" href="#" onclick="I('privacyPolicy').style.display=''">隐私政策</a>
<?php } ?>
<div id="test">
<div class="testGroup">
<div class="testArea2">
<div class="testName">Ping</div>
<div class="testName">延迟</div>
<div id="pingText" class="meterText" style="color:#AA6060"></div>
<div class="unit">ms</div>
</div>
<div class="testArea2">
<div class="testName">Jitter</div>
<div class="testName">抖动</div>
<div id="jitText" class="meterText" style="color:#AA6060"></div>
<div class="unit">ms</div>
</div>
</div>
<div class="testGroup">
<div class="testArea">
<div class="testName">Download</div>
<div class="testName">下载</div>
<canvas id="dlMeter" class="meter"></canvas>
<div id="dlText" class="meterText"></div>
<div class="unit">Mbit/s</div>
</div>
<div class="testArea">
<div class="testName">Upload</div>
<div class="testName">上传</div>
<canvas id="ulMeter" class="meter"></canvas>
<div id="ulText" class="meterText"></div>
<div class="unit">Mbit/s</div>
@ -316,51 +325,51 @@ function initUI(){
<span id="ip"></span>
</div>
<div id="shareArea" style="display:none">
<h3>Share results</h3>
<p>Test ID: <span id="testId"></span></p>
<input type="text" value="" id="resultsURL" readonly="readonly" onclick="this.select();this.focus();this.select();document.execCommand('copy');alert('Link copied')"/>
<img src="" id="resultsImg" />
<h3>被共享的测速结果</h3>
<p>测试 ID: <span id="testId"></span></p>
<input type="text" value="" id="resultsURL" readonly="readonly" style="display: none;" />
<img src="" id="resultsImg" onclick="copyResultsURL()" />
</div>
</div>
<a href="https://github.com/librespeed/speedtest">Source code</a>
由此获取本站 <a href="https://github.com/KUMAKAIHA/speedtest_chinese">源代码</a>
</div>
<div id="privacyPolicy" style="display:none">
<h2>Privacy Policy</h2>
<p>This HTML5 speed test server is configured with telemetry enabled.</p>
<h4>What data we collect</h4>
<h2>隐私政策</h2>
<p>此测速服务器已配置为启用遥测。</p>
<h4>我们收集哪些数据</h4>
<p>
At the end of the test, the following data is collected and stored:
在测试结束时,将收集并存储以下数据:
<ul>
<li>Test ID</li>
<li>Time of testing</li>
<li>Test results (download and upload speed, ping and jitter)</li>
<li>IP address</li>
<li>ISP information</li>
<li>Approximate location (inferred from IP address, not GPS)</li>
<li>User agent and browser locale</li>
<li>Test log (contains no personal information)</li>
<li>测试 ID</li>
<li>测试时间</li>
<li>测试结果下载速度、上传速度、ping 和抖动)</li>
<li>IP 地址</li>
<li>ISP 信息</li>
<li>大致位置(从 IP 地址推断,而非 GPS</li>
<li>用户代理和浏览器区域设置</li>
<li>测试日志(不包含个人信息)</li>
</ul>
</p>
<h4>How we use the data</h4>
<h4>我们如何使用数据</h4>
<p>
Data collected through this service is used to:
通过此服务收集的数据用于:
<ul>
<li>Allow sharing of test results (sharable image for forums, etc.)</li>
<li>To improve the service offered to you (for instance, to detect problems on our side)</li>
<li>允许分享测试结果(适用于论坛等的可共享图像)</li>
<li>改进为您提供的服务(例如,检测我们这一侧的问题)</li>
</ul>
No personal information is disclosed to third parties.
不会向第三方披露个人信息。
</p>
<h4>Your consent</h4>
<h4>您的同意</h4>
<p>
By starting the test, you consent to the terms of this privacy policy.
通过开始测试,您同意本隐私政策条款。
</p>
<h4>Data removal</h4>
<h4>数据删除</h4>
<p>
If you want to have your information deleted, you need to provide either the ID of the test or your IP address. This is the only way to identify your data, without this information we won't be able to comply with your request.<br/><br/>
Contact this email address for all deletion requests: <a href="mailto:<?=getenv("EMAIL") ?>"><?=getenv("EMAIL") ?></a>.
如果您希望删除您的信息,您需要提供测试 ID 或您的 IP 地址。这是唯一识别您数据的方式,没有这些信息,我们将无法满足您的请求。<br/><br/>
请通过以下电子邮件地址联系以获取所有删除请求: <a href="mailto:<?=getenv("EMAIL") ?>"><?=getenv("EMAIL") ?></a>
</p>
<br/><br/>
<a class="privacy" href="#" onclick="I('privacyPolicy').style.display='none'">Close</a><br/>
<a class="privacy" href="#" onclick="I('privacyPolicy').style.display='none'">关闭</a><br/>
</div>
<script type="text/javascript">setTimeout(function(){initUI()},100);</script>
</body>

View file

@ -159,14 +159,14 @@ function initUI(){
color:#FFFFFF;
}
#startStopBtn:before{
content:"Start";
content:"开始测速";
}
#startStopBtn.running:before{
content:"Abort";
content:"停止";
}
#test{
margin-top:2em;
margin-bottom:12em;
margin-bottom:10em;
}
div.testArea{
display:inline-block;
@ -273,35 +273,35 @@ function initUI(){
}
}
</style>
<title>LibreSpeed Example</title>
<title>服务器测速</title>
</head>
<body>
<h1>LibreSpeed Example</h1>
<h1>服务器点对点测速</h1>
<div id="testWrapper">
<div id="startStopBtn" onclick="startStop()"></div><br/>
<a class="privacy" href="#" onclick="I('privacyPolicy').style.display=''">Privacy</a>
<a class="privacy" href="#" onclick="I('privacyPolicy').style.display=''">隐私政策</a>
<div id="test">
<div class="testGroup">
<div class="testArea2">
<div class="testName">Ping</div>
<div class="testName">延迟</div>
<div id="pingText" class="meterText" style="color:#AA6060"></div>
<div class="unit">ms</div>
</div>
<div class="testArea2">
<div class="testName">Jitter</div>
<div class="testName">抖动</div>
<div id="jitText" class="meterText" style="color:#AA6060"></div>
<div class="unit">ms</div>
</div>
</div>
<div class="testGroup">
<div class="testArea">
<div class="testName">Download</div>
<div class="testName">下载</div>
<canvas id="dlMeter" class="meter"></canvas>
<div id="dlText" class="meterText"></div>
<div class="unit">Mbit/s</div>
</div>
<div class="testArea">
<div class="testName">Upload</div>
<div class="testName">上传</div>
<canvas id="ulMeter" class="meter"></canvas>
<div id="ulText" class="meterText"></div>
<div class="unit">Mbit/s</div>
@ -317,46 +317,46 @@ function initUI(){
<img src="" id="resultsImg" />
</div>
</div>
<a href="https://github.com/librespeed/speedtest">Source code</a>
由此获取本站 <a href="https://github.com/KUMAKAIHA/speedtest_chinese">源代码</a>
</div>
<div id="privacyPolicy" style="display:none">
<h2>Privacy Policy</h2>
<p>This HTML5 speed test server is configured with telemetry enabled.</p>
<h4>What data we collect</h4>
<h2>隐私政策</h2>
<p>此测速服务器已配置为启用遥测。</p>
<h4>我们收集哪些数据</h4>
<p>
At the end of the test, the following data is collected and stored:
在测试结束时,将收集并存储以下数据:
<ul>
<li>Test ID</li>
<li>Time of testing</li>
<li>Test results (download and upload speed, ping and jitter)</li>
<li>IP address</li>
<li>ISP information</li>
<li>Approximate location (inferred from IP address, not GPS)</li>
<li>User agent and browser locale</li>
<li>Test log (contains no personal information)</li>
<li>测试 ID</li>
<li>测试时间</li>
<li>测试结果下载速度、上传速度、ping 和抖动)</li>
<li>IP 地址</li>
<li>ISP 信息</li>
<li>大致位置(从 IP 地址推断,而非 GPS</li>
<li>用户代理和浏览器区域设置</li>
<li>测试日志(不包含个人信息)</li>
</ul>
</p>
<h4>How we use the data</h4>
<h4>我们如何使用数据</h4>
<p>
Data collected through this service is used to:
通过此服务收集的数据用于:
<ul>
<li>Allow sharing of test results (sharable image for forums, etc.)</li>
<li>To improve the service offered to you (for instance, to detect problems on our side)</li>
<li>允许分享测试结果(适用于论坛等的可共享图像)</li>
<li>改进为您提供的服务(例如,检测我们这一侧的问题)</li>
</ul>
No personal information is disclosed to third parties.
不会向第三方披露个人信息。
</p>
<h4>Your consent</h4>
<h4>您的同意</h4>
<p>
By starting the test, you consent to the terms of this privacy policy.
通过开始测试,您同意本隐私政策条款。
</p>
<h4>Data removal</h4>
<h4>数据删除</h4>
<p>
If you want to have your information deleted, you need to provide either the ID of the test or your IP address. This is the only way to identify your data, without this information we won't be able to comply with your request.<br/><br/>
Contact this email address for all deletion requests: <a href="mailto:PUT@YOUR_EMAIL.HERE">TO BE FILLED BY DEVELOPER</a>.
如果您希望删除您的信息,您需要提供测试 ID 或您的 IP 地址。这是唯一识别您数据的方式,没有这些信息,我们将无法满足您的请求。<br/><br/>
请通过以下电子邮件地址联系以获取所有删除请求: <a href="邮箱地址">邮箱地址</a>
</p>
<br/><br/>
<div class="closePrivacyPolicy">
<a class="privacy" href="#" onclick="I('privacyPolicy').style.display='none'">Close</a>
<a class="privacy" href="#" onclick="I('privacyPolicy').style.display='none'">关闭</a>
</div>
<br/>
</div>

View file

@ -164,52 +164,54 @@ function drawImage($speedtest)
// configure labels
$MBPS_TEXT = 'Mbit/s';
$MS_TEXT = 'ms';
$PING_TEXT = 'Ping';
$JIT_TEXT = 'Jitter';
$DL_TEXT = 'Download';
$UL_TEXT = 'Upload';
$WATERMARK_TEXT = 'LibreSpeed';
$PING_TEXT = '延迟';
$JIT_TEXT = '抖动';
$DL_TEXT = '下载';
$UL_TEXT = '上传';
$WATERMARK_TEXT = 'KUMAKAIHA';
$fontPath = '/var/www/html/results/simhei.ttf';
// create text boxes for each part of the image
$mbpsBbox = imageftbbox($FONT_MEASURE_SIZE_BIG, 0, $FONT_MEASURE, $MBPS_TEXT);
$msBbox = imageftbbox($FONT_MEASURE_SIZE, 0, $FONT_MEASURE, $MS_TEXT);
$pingBbox = imageftbbox($FONT_LABEL_SIZE, 0, $FONT_LABEL, $PING_TEXT);
$pingMeterBbox = imageftbbox($FONT_METER_SIZE, 0, $FONT_METER, $ping);
$jitBbox = imageftbbox($FONT_LABEL_SIZE, 0, $FONT_LABEL, $JIT_TEXT);
$jitMeterBbox = imageftbbox($FONT_METER_SIZE, 0, $FONT_METER, $jit);
$dlBbox = imageftbbox($FONT_LABEL_SIZE_BIG, 0, $FONT_LABEL, $DL_TEXT);
$dlMeterBbox = imageftbbox($FONT_METER_SIZE_BIG, 0, $FONT_METER, $dl);
$ulBbox = imageftbbox($FONT_LABEL_SIZE_BIG, 0, $FONT_LABEL, $UL_TEXT);
$ulMeterBbox = imageftbbox($FONT_METER_SIZE_BIG, 0, $FONT_METER, $ul);
$watermarkBbox = imageftbbox($FONT_WATERMARK_SIZE, 0, $FONT_WATERMARK, $WATERMARK_TEXT);
$mbpsBbox = imageftbbox($FONT_MEASURE_SIZE_BIG, 0, $fontPath, $MBPS_TEXT);
$msBbox = imageftbbox($FONT_MEASURE_SIZE, 0, $fontPath, $MS_TEXT);
$pingBbox = imageftbbox($FONT_LABEL_SIZE, 0, $fontPath, $PING_TEXT);
$pingMeterBbox = imageftbbox($FONT_METER_SIZE, 0, $fontPath, $ping);
$jitBbox = imageftbbox($FONT_LABEL_SIZE, 0, $fontPath, $JIT_TEXT);
$jitMeterBbox = imageftbbox($FONT_METER_SIZE, 0, $fontPath, $jit);
$dlBbox = imageftbbox($FONT_LABEL_SIZE_BIG, 0, $fontPath, $DL_TEXT);
$dlMeterBbox = imageftbbox($FONT_METER_SIZE_BIG, 0, $fontPath, $dl);
$ulBbox = imageftbbox($FONT_LABEL_SIZE_BIG, 0, $fontPath, $UL_TEXT);
$ulMeterBbox = imageftbbox($FONT_METER_SIZE_BIG, 0, $fontPath, $ul);
$watermarkBbox = imageftbbox($FONT_WATERMARK_SIZE, 0, $fontPath, $WATERMARK_TEXT);
$POSITION_X_WATERMARK = $WIDTH - $watermarkBbox[4] - 4 * $SCALE;
// put the parts together to draw the image
imagefilledrectangle($im, 0, 0, $WIDTH, $HEIGHT, $BACKGROUND_COLOR);
// ping
imagefttext($im, $FONT_LABEL_SIZE, 0, $POSITION_X_PING - $pingBbox[4] / 2, $POSITION_Y_PING_LABEL, $TEXT_COLOR_LABEL, $FONT_LABEL, $PING_TEXT);
imagefttext($im, $FONT_METER_SIZE, 0, $POSITION_X_PING - $pingMeterBbox[4] / 2 - $msBbox[4] / 2 - $SMALL_SEP / 2, $POSITION_Y_PING_METER, $TEXT_COLOR_PING_METER, $FONT_METER, $ping);
imagefttext($im, $FONT_MEASURE_SIZE, 0, $POSITION_X_PING + $pingMeterBbox[4] / 2 + $SMALL_SEP / 2 - $msBbox[4] / 2, $POSITION_Y_PING_MEASURE, $TEXT_COLOR_MEASURE, $FONT_MEASURE, $MS_TEXT);
imagefttext($im, $FONT_LABEL_SIZE, 0, $POSITION_X_PING - $pingBbox[4] / 2, $POSITION_Y_PING_LABEL, $TEXT_COLOR_LABEL, $fontPath, $PING_TEXT);
imagefttext($im, $FONT_METER_SIZE, 0, $POSITION_X_PING - $pingMeterBbox[4] / 2 - $msBbox[4] / 2 - $SMALL_SEP / 2, $POSITION_Y_PING_METER, $TEXT_COLOR_PING_METER, $fontPath, $ping);
imagefttext($im, $FONT_MEASURE_SIZE, 0, $POSITION_X_PING + $pingMeterBbox[4] / 2 + $SMALL_SEP / 2 - $msBbox[4] / 2, $POSITION_Y_PING_MEASURE, $TEXT_COLOR_MEASURE, $fontPath, $MS_TEXT);
// jitter
imagefttext($im, $FONT_LABEL_SIZE, 0, $POSITION_X_JIT - $jitBbox[4] / 2, $POSITION_Y_JIT_LABEL, $TEXT_COLOR_LABEL, $FONT_LABEL, $JIT_TEXT);
imagefttext($im, $FONT_METER_SIZE, 0, $POSITION_X_JIT - $jitMeterBbox[4] / 2 - $msBbox[4] / 2 - $SMALL_SEP / 2, $POSITION_Y_JIT_METER, $TEXT_COLOR_JIT_METER, $FONT_METER, $jit);
imagefttext($im, $FONT_MEASURE_SIZE, 0, $POSITION_X_JIT + $jitMeterBbox[4] / 2 + $SMALL_SEP / 2 - $msBbox[4] / 2, $POSITION_Y_JIT_MEASURE, $TEXT_COLOR_MEASURE, $FONT_MEASURE, $MS_TEXT);
imagefttext($im, $FONT_LABEL_SIZE, 0, $POSITION_X_JIT - $jitBbox[4] / 2, $POSITION_Y_JIT_LABEL, $TEXT_COLOR_LABEL, $fontPath, $JIT_TEXT);
imagefttext($im, $FONT_METER_SIZE, 0, $POSITION_X_JIT - $jitMeterBbox[4] / 2 - $msBbox[4] / 2 - $SMALL_SEP / 2, $POSITION_Y_JIT_METER, $TEXT_COLOR_JIT_METER, $fontPath, $jit);
imagefttext($im, $FONT_MEASURE_SIZE, 0, $POSITION_X_JIT + $jitMeterBbox[4] / 2 + $SMALL_SEP / 2 - $msBbox[4] / 2, $POSITION_Y_JIT_MEASURE, $TEXT_COLOR_MEASURE, $fontPath, $MS_TEXT);
// dl
imagefttext($im, $FONT_LABEL_SIZE_BIG, 0, $POSITION_X_DL - $dlBbox[4] / 2, $POSITION_Y_DL_LABEL, $TEXT_COLOR_LABEL, $FONT_LABEL, $DL_TEXT);
imagefttext($im, $FONT_METER_SIZE_BIG, 0, $POSITION_X_DL - $dlMeterBbox[4] / 2, $POSITION_Y_DL_METER, $TEXT_COLOR_DL_METER, $FONT_METER, $dl);
imagefttext($im, $FONT_MEASURE_SIZE_BIG, 0, $POSITION_X_DL - $mbpsBbox[4] / 2, $POSITION_Y_DL_MEASURE, $TEXT_COLOR_MEASURE, $FONT_MEASURE, $MBPS_TEXT);
imagefttext($im, $FONT_LABEL_SIZE_BIG, 0, $POSITION_X_DL - $dlBbox[4] / 2, $POSITION_Y_DL_LABEL, $TEXT_COLOR_LABEL, $fontPath, $DL_TEXT);
imagefttext($im, $FONT_METER_SIZE_BIG, 0, $POSITION_X_DL - $dlMeterBbox[4] / 2, $POSITION_Y_DL_METER, $TEXT_COLOR_DL_METER, $fontPath, $dl);
imagefttext($im, $FONT_MEASURE_SIZE_BIG, 0, $POSITION_X_DL - $mbpsBbox[4] / 2, $POSITION_Y_DL_MEASURE, $TEXT_COLOR_MEASURE, $fontPath, $MBPS_TEXT);
// ul
imagefttext($im, $FONT_LABEL_SIZE_BIG, 0, $POSITION_X_UL - $ulBbox[4] / 2, $POSITION_Y_UL_LABEL, $TEXT_COLOR_LABEL, $FONT_LABEL, $UL_TEXT);
imagefttext($im, $FONT_METER_SIZE_BIG, 0, $POSITION_X_UL - $ulMeterBbox[4] / 2, $POSITION_Y_UL_METER, $TEXT_COLOR_UL_METER, $FONT_METER, $ul);
imagefttext($im, $FONT_MEASURE_SIZE_BIG, 0, $POSITION_X_UL - $mbpsBbox[4] / 2, $POSITION_Y_UL_MEASURE, $TEXT_COLOR_MEASURE, $FONT_MEASURE, $MBPS_TEXT);
imagefttext($im, $FONT_LABEL_SIZE_BIG, 0, $POSITION_X_UL - $ulBbox[4] / 2, $POSITION_Y_UL_LABEL, $TEXT_COLOR_LABEL, $fontPath, $UL_TEXT);
imagefttext($im, $FONT_METER_SIZE_BIG, 0, $POSITION_X_UL - $ulMeterBbox[4] / 2, $POSITION_Y_UL_METER, $TEXT_COLOR_UL_METER, $fontPath, $ul);
imagefttext($im, $FONT_MEASURE_SIZE_BIG, 0, $POSITION_X_UL - $mbpsBbox[4] / 2, $POSITION_Y_UL_MEASURE, $TEXT_COLOR_MEASURE, $fontPath, $MBPS_TEXT);
// isp
imagefttext($im, $FONT_ISP_SIZE, 0, $POSITION_X_ISP, $POSITION_Y_ISP, $TEXT_COLOR_ISP, $FONT_ISP, $ispinfo);
imagefttext($im, $FONT_ISP_SIZE, 0, $POSITION_X_ISP, $POSITION_Y_ISP, $TEXT_COLOR_ISP, $fontPath, $ispinfo);
// separator
imagefilledrectangle($im, 0, $SEPARATOR_Y, $WIDTH, $SEPARATOR_Y, $SEPARATOR_COLOR);
// timestamp
imagefttext($im, $FONT_TIMESTAMP_SIZE, 0, $POSITION_X_TIMESTAMP, $POSITION_Y_TIMESTAMP, $TEXT_COLOR_TIMESTAMP, $FONT_TIMESTAMP, $timestamp);
imagefttext($im, $FONT_TIMESTAMP_SIZE, 0, $POSITION_X_TIMESTAMP, $POSITION_Y_TIMESTAMP, $TEXT_COLOR_TIMESTAMP, $fontPath, $timestamp);
// watermark
imagefttext($im, $FONT_WATERMARK_SIZE, 0, $POSITION_X_WATERMARK, $POSITION_Y_WATERMARK, $TEXT_COLOR_WATERMARK, $FONT_WATERMARK, $WATERMARK_TEXT);
imagefttext($im, $FONT_WATERMARK_SIZE, 0, $POSITION_X_WATERMARK, $POSITION_Y_WATERMARK, $TEXT_COLOR_WATERMARK, $fontPath, $WATERMARK_TEXT);
// send the image to the browser
header('Content-Type: image/png');

BIN
results/simhei.ttf Normal file

Binary file not shown.

View file

@ -13,7 +13,7 @@ header('Pragma: no-cache');
<!DOCTYPE html>
<html>
<head>
<title>LibreSpeed - Stats</title>
<title>服务器测速 - 统计</title>
<style type="text/css">
html,body{
margin:0;
@ -61,11 +61,11 @@ header('Pragma: no-cache');
</style>
</head>
<body>
<h1>LibreSpeed - Stats</h1>
<h1>服务器测速 - 统计</h1>
<?php
if (!isset($stats_password) || $stats_password === 'PASSWORD') {
?>
Please set $stats_password in telemetry_settings.php to enable access.
请在telemetry_settings.php中设置$stats_password以启用访问。
<?php
} elseif ($_SESSION['logged'] === true) {
if ($_GET['op'] === 'logout') {
@ -73,79 +73,84 @@ header('Pragma: no-cache');
?><script type="text/javascript">window.location=location.protocol+"//"+location.host+location.pathname;</script><?php
} else {
?>
<form action="stats.php" method="GET"><input type="hidden" name="op" value="logout" /><input type="submit" value="Logout" /></form>
<form action="stats.php" method="GET">
<h3>Search test results</h3>
<input type="hidden" name="op" value="logout" />
<input type="submit" value="登出" />
<input type="button" value="返回" onclick="window.location.href = window.location.origin;" style="margin-left: 10px;" />
</form>
<form action="stats.php" method="GET">
<h3>搜索测速结果</h3>
<input type="hidden" name="op" value="id" />
<input type="text" name="id" id="id" placeholder="Test ID" value=""/>
<input type="submit" value="Find" />
<input type="submit" onclick="document.getElementById('id').value=''" value="Show last 100 tests" />
<input type="text" name="id" id="id" placeholder="测试 ID" value=""/>
<input type="submit" value="查找" />
<input type="submit" onclick="document.getElementById('id').value=''" value="显示最近100次测试" />
</form>
<?php
if ($_GET['op'] === 'id' && !empty($_GET['id'])) {
$speedtest = getSpeedtestUserById($_GET['id']);
$speedtests = [];
if (false === $speedtest) {
echo '<div>There was an error trying to fetch the speedtest result for ID "'.htmlspecialchars($_GET['id'], ENT_HTML5, 'UTF-8').'".</div>';
echo '<div>尝试获取 ID "'.htmlspecialchars($_GET['id'], ENT_HTML5, 'UTF-8').'" 的速度测试结果时出现错误。</div>';
} elseif (null === $speedtest) {
echo '<div>Could not find a speedtest result for ID "'.htmlspecialchars($_GET['id'], ENT_HTML5, 'UTF-8').'".</div>';
echo '<div>未找到 ID "'.htmlspecialchars($_GET['id'], ENT_HTML5, 'UTF-8').'" 的速度测试结果。</div>';
} else {
$speedtests = [$speedtest];
}
} else {
$speedtests = getLatestSpeedtestUsers();
if (false === $speedtests) {
echo '<div>There was an error trying to fetch latest speedtest results.</div>';
echo '<div>尝试获取最新速度测试结果时出现错误。</div>';
} elseif (empty($speedtests)) {
echo '<div>Could not find any speedtest results in database.</div>';
echo '<div>数据库中找不到任何速度测试结果。</div>';
}
}
foreach ($speedtests as $speedtest) {
?>
<table>
<tr>
<th>Test ID</th>
<th>测试 ID</th>
<td><?= htmlspecialchars($speedtest['id_formatted'], ENT_HTML5, 'UTF-8') ?></td>
</tr>
<tr>
<th>Date and time</th>
<th>日期与时间</th>
<td><?= htmlspecialchars($speedtest['timestamp'], ENT_HTML5, 'UTF-8') ?></td>
</tr>
<tr>
<th>IP and ISP Info</th>
<th>IP和ISP信息</th>
<td>
<?= htmlspecialchars($speedtest['ip'], ENT_HTML5, 'UTF-8') ?><br/>
<?= htmlspecialchars($speedtest['ispinfo'], ENT_HTML5, 'UTF-8') ?>
</td>
</tr>
<tr>
<th>User agent and locale</th>
<th>设备信息</th>
<td><?= htmlspecialchars($speedtest['ua'], ENT_HTML5, 'UTF-8') ?><br/>
<?= htmlspecialchars($speedtest['lang'], ENT_HTML5, 'UTF-8') ?>
</td>
</tr>
<tr>
<th>Download speed</th>
<th>下载速度</th>
<td><?= htmlspecialchars($speedtest['dl'], ENT_HTML5, 'UTF-8') ?></td>
</tr>
<tr>
<th>Upload speed</th>
<th>上传速度</th>
<td><?= htmlspecialchars($speedtest['ul'], ENT_HTML5, 'UTF-8') ?></td>
</tr>
<tr>
<th>Ping</th>
<th>延迟</th>
<td><?= htmlspecialchars($speedtest['ping'], ENT_HTML5, 'UTF-8') ?></td>
</tr>
<tr>
<th>Jitter</th>
<th>抖动</th>
<td><?= htmlspecialchars($speedtest['jitter'], ENT_HTML5, 'UTF-8') ?></td>
</tr>
<tr>
<th>Log</th>
<th>日志</th>
<td><?= htmlspecialchars($speedtest['log'], ENT_HTML5, 'UTF-8') ?></td>
</tr>
<tr>
<th>Extra info</th>
<th>其它信息</th>
<td><?= htmlspecialchars($speedtest['extra'], ENT_HTML5, 'UTF-8') ?></td>
</tr>
</table>
@ -158,12 +163,12 @@ header('Pragma: no-cache');
} else {
?>
<form action="stats.php?op=login" method="POST">
<h3>Login</h3>
<input type="password" name="password" placeholder="Password" value=""/>
<input type="submit" value="Login" />
<h3>登录</h3>
<input type="password" name="password" placeholder="密码" value=""/>
<input type="submit" value="登录" />
</form>
<?php
}
?>
</body>
</html>
</html>

View file

@ -5,11 +5,11 @@ require_once 'idObfuscation.php';
define('TELEMETRY_SETTINGS_FILE', 'telemetry_settings.php');
$tz = getenv('TZ');
if ($tz !== false) {
// If the environment variable TZ exists, set the default timezone for PHP to that value
// 如果环境变量TZ存在则设置PHP的默认时区为该值
date_default_timezone_set($tz);
} else {
// If the environment variable TZ does not exist, set a default timezone or handle the error
// Set it to Asia/Shanghai
// 如果环境变量TZ不存在设置一个默认时区或者处理错误
// 设置为Asia/Shanghai
date_default_timezone_set('Asia/Shanghai');
}
/**
@ -192,13 +192,13 @@ function insertSpeedtestUser($ip, $ispinfo, $extra, $ua, $lang, $dl, $ul, $ping,
}
try {
$currentTimestamp = new DateTime('now');
$currentTimestamp = new DateTime('now'); // 这里会自动使用 PHP 配置的时区
$formattedTimestamp = $currentTimestamp->format('Y-m-d H:i:s');
$stmt = $pdo->prepare(
'INSERT INTO speedtest_users
(ip,ispinfo,extra,ua,lang,dl,ul,ping,jitter,log,timestamp)
VALUES (?,?,?,?,?,?,?,?,?,?,?)'
VALUES (?,?,?,?,?,?,?,?,?,?,?)' // 这里添加了timestamp字段
);
$stmt->execute([
$ip, $ispinfo, $extra, $ua, $lang, $dl, $ul, $ping, $jitter, $log, $formattedTimestamp // 在execute的参数中添加$formattedTimestamp
@ -210,6 +210,7 @@ function insertSpeedtestUser($ip, $ispinfo, $extra, $ua, $lang, $dl, $ul, $ping,
}
return false;
}
if (isObfuscationEnabled()) {
return obfuscateId($id);

View file

@ -49,7 +49,7 @@ function Speedtest() {
this._settings = {}; //settings for the speed test worker
this._state = 0; //0=adding settings, 1=adding servers, 2=server selection done, 3=test running, 4=done
console.log(
"LibreSpeed by Federico Dossena v5.3.0 - https://github.com/librespeed/speedtest"
"LibreSpeed by Federico Dossena v5.2.5 - https://github.com/librespeed/speedtest"
);
}