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 # 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. 支持所有现代浏览器IE11、最新版Edge、最新版Chrome、最新版Firefox、最新版Safari。
Works with mobile versions too. 同样适用于移动版本。
## Features ## 特性
* Download * 下载速度
* Upload * 上传速度
* Ping * 延迟(Ping
* Jitter * 抖动(Jitter
* IP Address, ISP, distance from server (optional) * IP地址、ISP、与服务器的距离可选
* Telemetry (optional) * 遥测数据(可选)
* Results sharing (optional) * 结果分享(可选)
* Multiple Points of Test (optional) * 多点测试(可选)
![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安装步骤相当简单。
* PHP 5.4 or newer (other backends also available) 我在QNAP上设置了这个。
* MySQL database to store test results (optional, Microsoft SQL Server, PostgreSQL and SQLite also supported) 以此次为例,我在网络共享区域使用了一个名为**speedtest**的文件夹。
* A fast! internet connection
## Installation 1. 选择example-xxx.html文件中的一个作为你speedtest文件夹中的新index.html。我使用的是example-singleServer-full.html
Assuming you have PHP installed, the installation steps are quite simple. 2. 将speedtest.js、speedtest_worker.js和favicon.ico添加到你的speedtest文件夹中。
I set this up on a QNAP. 3. 将整个backend文件夹下载到speedtest/backend中。
For this example, I am using a folder called **speedtest** in my web share area. 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. * [Ubuntu Server 19.04快速开始安装指南](https://fdossena.com/?p=speedtest/quickstart_v5_ubuntu.frag)
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 ## Android应用
There is a more in-depth installation video here: 为你的LibreSpeed安装构建Android客户端的模板可以在[这里](https://github.com/librespeed/speedtest-android)找到。
* [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).
## Docker ## 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 ## Go后端
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实现版本可以在[`speedtest-go`](https://github.com/librespeed/speedtest-go)仓库中找到,由[Maddie Zhan](https://github.com/maddie)维护。
## Node.js backend ## Node.js后端
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`分支中有一个部分实现的Node.js版本由[dunklesToast](https://github.com/dunklesToast)开发。目前不推荐使用。
## Donate ## 捐赠
[![Donate with Liberapay](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/fdossena/donate) [![通过Liberapay捐赠](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/fdossena/donate)
[Donate with PayPal](https://www.paypal.me/sineisochronic) [通过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 这个程序是自由软件你可以在GNU Lesser General Public License的条款下重新分发和/或修改它该许可证由自由软件基金会发布要么是许可证的第3版或者根据你的选择任何后续版本。
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.
This program is distributed in the hope that it will be useful, 这个程序希望它是有用的,
but WITHOUT ANY WARRANTY; without even the implied warranty of 但没有任何保证甚至没有暗示的保证MERCHANTABILITY或特定目的的适用性。详情请参见GNU通用公共许可证。
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 你应该已经收到了GNU Lesser General Public License的副本
along with this program. If not, see <https://www.gnu.org/licenses/lgpl>. 和这个程序一起。如果没有,参见<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`. A login is required to access the interface. __Important__: change the default password in `results/telemetry_settings.php`.
#### The end #### 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. 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 #### 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. 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 ### Multiple servers, PHP
The speed test can automatically choose between multiple test points and use the one with the lowest ping in a list. 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-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-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 * `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:__ __Multiple servers:__
* `example-multipleServers-pretty.html`: Same as `example-singleServer-pretty.html` but with multiple test points. Server selection is fully automatic * `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 ### Initialization
To use the speed test in your page, first you need to load it: 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 ## 下载 Docker 镜像
To download LibreSpeed from the docker repo, use this command: 要从 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 ## 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 ```yml
version: '3.7' version: '3.7'
services: services:
speedtest: speedtest:
container_name: speedtest container_name: speedtest
image: ghcr.io/librespeed/speedtest:latest image: ghcr.io/kumakaiha/speedtest:latest
restart: always restart: always
environment: environment:
MODE: standalone MODE: standalone
@ -35,72 +34,73 @@ services:
- "80:80" # webport mapping (host:container) - "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` * __`TITLE`__: 您的速度测试标题。默认值:`LibreSpeed`
* __`TELEMETRY`__: Whether to enable telemetry or not. If enabled, you maybe want your data to be persisted. See below. Default value: `false` * __`TELEMETRY`__: 是否启用遥测。如果启用,您可能希望持久保存数据。请参见下文。默认值:`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` * __`ENABLE_ID_OBFUSCATION`__: 当启用遥测并设置为 true 时,测试 ID 将被模糊化,以避免暴露数据库内部的顺序 ID。默认值`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` * __`REDACT_IP_ADDRESSES`__: 当启用遥测并设置为 true 时IP 地址和主机名将从收集的遥测数据中删除,以提高隐私性。默认值:`false`
* __`PASSWORD`__: Password to access the stats page. If not set, stats page will not allow accesses. * __`PASSWORD`__: 访问统计页面的密码。如果未设置,统计页面将不允许访问。
* __`EMAIL`__: Email address for GDPR requests. Must be specified when telemetry is enabled. * __`EMAIL`__: GDPR 请求的电子邮件地址。在启用遥测时必须指定。
* __`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 密钥。可选,但如果您希望提供大量测试,则需要。
* __`DISABLE_IPINFO`__: If set to true, ISP info and distance will not be fetched from ipinfo.io. Default: value: `false` * __`DISABLE_IPINFO`__: 如果设置为 true则不会从 ipinfo.io 获取 ISP 信息和距离。默认值:`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` * __`DISTANCE`__: 当 `DISABLE_IPINFO` 设置为 false 时,指定从服务器测量的距离方式。可以是 `km` 表示千米,`mi` 表示英里,或空字符串表示禁用距离测量。默认值:`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 * __`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 此命令在端口 80 上使用默认设置以独立模式启动 LibreSpeed
This command starts LibreSpeed in standalone mode, with the default settings, on port 80:
``` ```
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 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: 在前端模式下LibreSpeed 为客户端提供 Web 用户界面和服务器列表。为此:
* Set the `MODE` environment variable to `frontend` * `MODE` 环境变量设置为 `frontend`
* Create a servers.json file with your test points. The syntax is the following: * 使用您的测试点创建一个 servers.json 文件。语法如下:
``` ```
[ [
{ {
"name": "Friendly name for Server 1", "name": "服务器 1 的友好名称",
"server" :"//server1.mydomain.com/", "server" :"//server1.mydomain.com/",
"dlURL" :"garbage.php", "dlURL" :"garbage.php",
"ulURL" :"empty.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" "getIpURL" :"getIP.php"
}, },
{ {
"name": "Friendly name for Server 2", "name": "服务器 2 的友好名称",
"server" :"https://server2.mydomain.com/", "server" :"https://server2.mydomain.com/",
"dlURL" :"garbage.php", "dlURL" :"garbage.php",
"ulURL" :"empty.php", "ulURL" :"empty.php",
"pingURL" :"empty.php", "pingURL" :"empty.php",
"getIpURL" :"getIP.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 `//`. 注意:如果服务器仅支持 HTTP 或 HTTPS请在服务器字段中指定协议。如果两者都支持请使用 `//`
* Mount this file to `/servers.json` in the container (example at the end of this file) * 将此文件挂载到容器中的 `/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` * __`TITLE`__: 您的速度测试标题。默认值:`LibreSpeed`
* __`TELEMETRY`__: Whether to enable telemetry or not. Default value: `false` * __`TELEMETRY`__: 是否启用遥测。默认值:`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` * __`ENABLE_ID_OBFUSCATION`__: 当启用遥测并设置为 true 时,测试 ID 将被模糊化,以避免暴露数据库内部的顺序 ID。默认值`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` * __`REDACT_IP_ADDRESSES`__: 当启用遥测并设置为 true 时IP 地址和主机名将从收集的遥测数据中删除,以提高隐私性。默认值:`false`
* __`PASSWORD`__: Password to access the stats page. If not set, stats page will not allow accesses. * __`PASSWORD`__: 访问统计页面的密码。如果未设置,统计页面将不允许访问。
* __`EMAIL`__: Email address for GDPR requests. Must be specified when telemetry is enabled. * __`EMAIL`__: GDPR 请求的电子邮件地址。在启用遥测时必须指定。
* __`DISABLE_IPINFO`__: If set to true, ISP info and distance will not be fetched from ipinfo.io. Default: value: `false` * __`DISABLE_IPINFO`__: 如果设置为 true则不会从 ipinfo.io 获取 ISP 信息和距离。默认值:`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` * __`DISTANCE`__: 当 `DISABLE_IPINFO` 设置为 false 时,指定从服务器测量的距禂方式。可以是 `km` 表示千米,`mi` 表示英里,或空字符串表示禁用距离测量。默认值:`km`
* __`WEBPORT`__: Allows choosing a custom port for the included web server. Default value: `80` * __`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 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
``` ```
### 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.

View file

@ -1,48 +1,39 @@
#!/bin/bash #!/bin/bash
set -e set -e
set -x set -x
# Cleanup # Cleanup
rm -rf /var/www/html/* rm -rf /var/www/html/*
# Copy frontend files # Copy frontend files
cp /speedtest/*.js /var/www/html/ cp /speedtest/*.js /var/www/html/
# Copy favicon # Copy favicon
cp /speedtest/favicon.ico /var/www/html/ cp /speedtest/favicon.ico /var/www/html/
# Set up backend side for standlone modes # 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 cp -r /speedtest/backend/ /var/www/html/backend
if [ ! -z "$IPINFO_APIKEY" ]; then if [ ! -z "$IPINFO_APIKEY" ]; then
sed -i s/\$IPINFO_APIKEY\ =\ \'\'/\$IPINFO_APIKEY\ =\ \'$IPINFO_APIKEY\'/g /var/www/html/backend/getIP_ipInfo_apikey.php sed -i s/\$IPINFO_APIKEY\ =\ \'\'/\$IPINFO_APIKEY\ =\ \'$IPINFO_APIKEY\'/g /var/www/html/backend/getIP_ipInfo_apikey.php
fi fi
fi fi
if [ "$MODE" == "backend" ]; then if [ "$MODE" == "backend" ]; then
cp -r /speedtest/backend/* /var/www/html cp -r /speedtest/backend/* /var/www/html
if [ ! -z "$IPINFO_APIKEY" ]; then if [ ! -z "$IPINFO_APIKEY" ]; then
sed -i s/\$IPINFO_APIKEY\ =\ \'\'/\$IPINFO_APIKEY\ =\ \'$IPINFO_APIKEY\'/g /var/www/html/getIP_ipInfo_apikey.php sed -i s/\$IPINFO_APIKEY\ =\ \'\'/\$IPINFO_APIKEY\ =\ \'$IPINFO_APIKEY\'/g /var/www/html/getIP_ipInfo_apikey.php
fi fi
fi fi
# Set up index.php for frontend-only or standalone modes # 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 cp /speedtest/frontend.php /var/www/html/index.php
elif [ "$MODE" == "standalone" ]; then elif [ "$MODE" == "standalone" ]; then
cp /speedtest/standalone.php /var/www/html/index.php cp /speedtest/standalone.php /var/www/html/index.php
fi fi
# Apply Telemetry settings when running in standalone or frontend mode and telemetry is enabled # 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 cp -r /speedtest/results /var/www/html/results
if [ "$MODE" == "frontend" ]; then if [ "$MODE" == "frontend" ]; then
mkdir /var/www/html/backend mkdir /var/www/html/backend
cp /speedtest/backend/getIP_util.php /var/www/html/backend cp /speedtest/backend/getIP_util.php /var/www/html/backend
fi fi
if [ "$DB_TYPE" == "mysql" ]; then 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/$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 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 else
sed -i s/\$db_type\ =\ \'.*\'/\$db_type\ =\ \'sqlite\'\/g /var/www/html/results/telemetry_settings.php sed -i s/\$db_type\ =\ \'.*\'/\$db_type\ =\ \'sqlite\'\/g /var/www/html/results/telemetry_settings.php
fi fi
sed -i s/\$Sqlite_db_file\ =\ \'.*\'/\$Sqlite_db_file=\'\\\/database\\\/db.sql\'/g /var/www/html/results/telemetry_settings.php 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 sed -i s/\$stats_password\ =\ \'.*\'/\$stats_password\ =\ \'$PASSWORD\'/g /var/www/html/results/telemetry_settings.php
if [ "$ENABLE_ID_OBFUSCATION" == "true" ]; then if [ "$ENABLE_ID_OBFUSCATION" == "true" ]; then
sed -i s/\$enable_id_obfuscation\ =\ .*\;/\$enable_id_obfuscation\ =\ true\;/g /var/www/html/results/telemetry_settings.php sed -i s/\$enable_id_obfuscation\ =\ .*\;/\$enable_id_obfuscation\ =\ true\;/g /var/www/html/results/telemetry_settings.php
fi fi
if [ "$REDACT_IP_ADDRESSES" == "true" ]; then if [ "$REDACT_IP_ADDRESSES" == "true" ]; then
sed -i s/\$redact_ip_addresses\ =\ .*\;/\$redact_ip_addresses\ =\ true\;/g /var/www/html/results/telemetry_settings.php sed -i s/\$redact_ip_addresses\ =\ .*\;/\$redact_ip_addresses\ =\ true\;/g /var/www/html/results/telemetry_settings.php
fi fi
mkdir -p /database/ mkdir -p /database/
chown www-data /database/ chown www-data /database/
fi fi
chown -R www-data /var/www/html/* chown -R www-data /var/www/html/*
# Allow selection of Apache port for network_mode: host # Allow selection of Apache port for network_mode: host
if [ "$WEBPORT" != "80" ]; then if [ "$WEBPORT" != "80" ]; then
sed -i "s/^Listen 80\$/Listen $WEBPORT/g" /etc/apache2/ports.conf 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 fi
echo "Done, Starting APACHE" echo "Done, Starting APACHE"
# This runs apache # This runs apache
apache2-foreground apache2-foreground

View file

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

View file

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

View file

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

View file

@ -164,52 +164,54 @@ function drawImage($speedtest)
// configure labels // configure labels
$MBPS_TEXT = 'Mbit/s'; $MBPS_TEXT = 'Mbit/s';
$MS_TEXT = 'ms'; $MS_TEXT = 'ms';
$PING_TEXT = 'Ping'; $PING_TEXT = '延迟';
$JIT_TEXT = 'Jitter'; $JIT_TEXT = '抖动';
$DL_TEXT = 'Download'; $DL_TEXT = '下载';
$UL_TEXT = 'Upload'; $UL_TEXT = '上传';
$WATERMARK_TEXT = 'LibreSpeed'; $WATERMARK_TEXT = 'KUMAKAIHA';
$fontPath = '/var/www/html/results/simhei.ttf';
// create text boxes for each part of the image // create text boxes for each part of the image
$mbpsBbox = imageftbbox($FONT_MEASURE_SIZE_BIG, 0, $FONT_MEASURE, $MBPS_TEXT); $mbpsBbox = imageftbbox($FONT_MEASURE_SIZE_BIG, 0, $fontPath, $MBPS_TEXT);
$msBbox = imageftbbox($FONT_MEASURE_SIZE, 0, $FONT_MEASURE, $MS_TEXT); $msBbox = imageftbbox($FONT_MEASURE_SIZE, 0, $fontPath, $MS_TEXT);
$pingBbox = imageftbbox($FONT_LABEL_SIZE, 0, $FONT_LABEL, $PING_TEXT); $pingBbox = imageftbbox($FONT_LABEL_SIZE, 0, $fontPath, $PING_TEXT);
$pingMeterBbox = imageftbbox($FONT_METER_SIZE, 0, $FONT_METER, $ping); $pingMeterBbox = imageftbbox($FONT_METER_SIZE, 0, $fontPath, $ping);
$jitBbox = imageftbbox($FONT_LABEL_SIZE, 0, $FONT_LABEL, $JIT_TEXT); $jitBbox = imageftbbox($FONT_LABEL_SIZE, 0, $fontPath, $JIT_TEXT);
$jitMeterBbox = imageftbbox($FONT_METER_SIZE, 0, $FONT_METER, $jit); $jitMeterBbox = imageftbbox($FONT_METER_SIZE, 0, $fontPath, $jit);
$dlBbox = imageftbbox($FONT_LABEL_SIZE_BIG, 0, $FONT_LABEL, $DL_TEXT); $dlBbox = imageftbbox($FONT_LABEL_SIZE_BIG, 0, $fontPath, $DL_TEXT);
$dlMeterBbox = imageftbbox($FONT_METER_SIZE_BIG, 0, $FONT_METER, $dl); $dlMeterBbox = imageftbbox($FONT_METER_SIZE_BIG, 0, $fontPath, $dl);
$ulBbox = imageftbbox($FONT_LABEL_SIZE_BIG, 0, $FONT_LABEL, $UL_TEXT); $ulBbox = imageftbbox($FONT_LABEL_SIZE_BIG, 0, $fontPath, $UL_TEXT);
$ulMeterBbox = imageftbbox($FONT_METER_SIZE_BIG, 0, $FONT_METER, $ul); $ulMeterBbox = imageftbbox($FONT_METER_SIZE_BIG, 0, $fontPath, $ul);
$watermarkBbox = imageftbbox($FONT_WATERMARK_SIZE, 0, $FONT_WATERMARK, $WATERMARK_TEXT); $watermarkBbox = imageftbbox($FONT_WATERMARK_SIZE, 0, $fontPath, $WATERMARK_TEXT);
$POSITION_X_WATERMARK = $WIDTH - $watermarkBbox[4] - 4 * $SCALE; $POSITION_X_WATERMARK = $WIDTH - $watermarkBbox[4] - 4 * $SCALE;
// put the parts together to draw the image // put the parts together to draw the image
imagefilledrectangle($im, 0, 0, $WIDTH, $HEIGHT, $BACKGROUND_COLOR); imagefilledrectangle($im, 0, 0, $WIDTH, $HEIGHT, $BACKGROUND_COLOR);
// ping // 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_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, $FONT_METER, $ping); 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, $FONT_MEASURE, $MS_TEXT); 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 // 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_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, $FONT_METER, $jit); 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, $FONT_MEASURE, $MS_TEXT); 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 // 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_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, $FONT_METER, $dl); 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, $FONT_MEASURE, $MBPS_TEXT); imagefttext($im, $FONT_MEASURE_SIZE_BIG, 0, $POSITION_X_DL - $mbpsBbox[4] / 2, $POSITION_Y_DL_MEASURE, $TEXT_COLOR_MEASURE, $fontPath, $MBPS_TEXT);
// ul // 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_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, $FONT_METER, $ul); 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, $FONT_MEASURE, $MBPS_TEXT); imagefttext($im, $FONT_MEASURE_SIZE_BIG, 0, $POSITION_X_UL - $mbpsBbox[4] / 2, $POSITION_Y_UL_MEASURE, $TEXT_COLOR_MEASURE, $fontPath, $MBPS_TEXT);
// isp // 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 // separator
imagefilledrectangle($im, 0, $SEPARATOR_Y, $WIDTH, $SEPARATOR_Y, $SEPARATOR_COLOR); imagefilledrectangle($im, 0, $SEPARATOR_Y, $WIDTH, $SEPARATOR_Y, $SEPARATOR_COLOR);
// timestamp // 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 // 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 // send the image to the browser
header('Content-Type: image/png'); 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> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>LibreSpeed - Stats</title> <title>服务器测速 - 统计</title>
<style type="text/css"> <style type="text/css">
html,body{ html,body{
margin:0; margin:0;
@ -61,11 +61,11 @@ header('Pragma: no-cache');
</style> </style>
</head> </head>
<body> <body>
<h1>LibreSpeed - Stats</h1> <h1>服务器测速 - 统计</h1>
<?php <?php
if (!isset($stats_password) || $stats_password === 'PASSWORD') { if (!isset($stats_password) || $stats_password === 'PASSWORD') {
?> ?>
Please set $stats_password in telemetry_settings.php to enable access. 请在telemetry_settings.php中设置$stats_password以启用访问。
<?php <?php
} elseif ($_SESSION['logged'] === true) { } elseif ($_SESSION['logged'] === true) {
if ($_GET['op'] === 'logout') { 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 ?><script type="text/javascript">window.location=location.protocol+"//"+location.host+location.pathname;</script><?php
} else { } 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"> <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="hidden" name="op" value="id" />
<input type="text" name="id" id="id" placeholder="Test ID" value=""/> <input type="text" name="id" id="id" placeholder="测试 ID" value=""/>
<input type="submit" value="Find" /> <input type="submit" value="查找" />
<input type="submit" onclick="document.getElementById('id').value=''" value="Show last 100 tests" /> <input type="submit" onclick="document.getElementById('id').value=''" value="显示最近100次测试" />
</form> </form>
<?php <?php
if ($_GET['op'] === 'id' && !empty($_GET['id'])) { if ($_GET['op'] === 'id' && !empty($_GET['id'])) {
$speedtest = getSpeedtestUserById($_GET['id']); $speedtest = getSpeedtestUserById($_GET['id']);
$speedtests = []; $speedtests = [];
if (false === $speedtest) { 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) { } 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 { } else {
$speedtests = [$speedtest]; $speedtests = [$speedtest];
} }
} else { } else {
$speedtests = getLatestSpeedtestUsers(); $speedtests = getLatestSpeedtestUsers();
if (false === $speedtests) { if (false === $speedtests) {
echo '<div>There was an error trying to fetch latest speedtest results.</div>'; echo '<div>尝试获取最新速度测试结果时出现错误。</div>';
} elseif (empty($speedtests)) { } elseif (empty($speedtests)) {
echo '<div>Could not find any speedtest results in database.</div>'; echo '<div>数据库中找不到任何速度测试结果。</div>';
} }
} }
foreach ($speedtests as $speedtest) { foreach ($speedtests as $speedtest) {
?> ?>
<table> <table>
<tr> <tr>
<th>Test ID</th> <th>测试 ID</th>
<td><?= htmlspecialchars($speedtest['id_formatted'], ENT_HTML5, 'UTF-8') ?></td> <td><?= htmlspecialchars($speedtest['id_formatted'], ENT_HTML5, 'UTF-8') ?></td>
</tr> </tr>
<tr> <tr>
<th>Date and time</th> <th>日期与时间</th>
<td><?= htmlspecialchars($speedtest['timestamp'], ENT_HTML5, 'UTF-8') ?></td> <td><?= htmlspecialchars($speedtest['timestamp'], ENT_HTML5, 'UTF-8') ?></td>
</tr> </tr>
<tr> <tr>
<th>IP and ISP Info</th> <th>IP和ISP信息</th>
<td> <td>
<?= htmlspecialchars($speedtest['ip'], ENT_HTML5, 'UTF-8') ?><br/> <?= htmlspecialchars($speedtest['ip'], ENT_HTML5, 'UTF-8') ?><br/>
<?= htmlspecialchars($speedtest['ispinfo'], ENT_HTML5, 'UTF-8') ?> <?= htmlspecialchars($speedtest['ispinfo'], ENT_HTML5, 'UTF-8') ?>
</td> </td>
</tr> </tr>
<tr> <tr>
<th>User agent and locale</th> <th>设备信息</th>
<td><?= htmlspecialchars($speedtest['ua'], ENT_HTML5, 'UTF-8') ?><br/> <td><?= htmlspecialchars($speedtest['ua'], ENT_HTML5, 'UTF-8') ?><br/>
<?= htmlspecialchars($speedtest['lang'], ENT_HTML5, 'UTF-8') ?> <?= htmlspecialchars($speedtest['lang'], ENT_HTML5, 'UTF-8') ?>
</td> </td>
</tr> </tr>
<tr> <tr>
<th>Download speed</th> <th>下载速度</th>
<td><?= htmlspecialchars($speedtest['dl'], ENT_HTML5, 'UTF-8') ?></td> <td><?= htmlspecialchars($speedtest['dl'], ENT_HTML5, 'UTF-8') ?></td>
</tr> </tr>
<tr> <tr>
<th>Upload speed</th> <th>上传速度</th>
<td><?= htmlspecialchars($speedtest['ul'], ENT_HTML5, 'UTF-8') ?></td> <td><?= htmlspecialchars($speedtest['ul'], ENT_HTML5, 'UTF-8') ?></td>
</tr> </tr>
<tr> <tr>
<th>Ping</th> <th>延迟</th>
<td><?= htmlspecialchars($speedtest['ping'], ENT_HTML5, 'UTF-8') ?></td> <td><?= htmlspecialchars($speedtest['ping'], ENT_HTML5, 'UTF-8') ?></td>
</tr> </tr>
<tr> <tr>
<th>Jitter</th> <th>抖动</th>
<td><?= htmlspecialchars($speedtest['jitter'], ENT_HTML5, 'UTF-8') ?></td> <td><?= htmlspecialchars($speedtest['jitter'], ENT_HTML5, 'UTF-8') ?></td>
</tr> </tr>
<tr> <tr>
<th>Log</th> <th>日志</th>
<td><?= htmlspecialchars($speedtest['log'], ENT_HTML5, 'UTF-8') ?></td> <td><?= htmlspecialchars($speedtest['log'], ENT_HTML5, 'UTF-8') ?></td>
</tr> </tr>
<tr> <tr>
<th>Extra info</th> <th>其它信息</th>
<td><?= htmlspecialchars($speedtest['extra'], ENT_HTML5, 'UTF-8') ?></td> <td><?= htmlspecialchars($speedtest['extra'], ENT_HTML5, 'UTF-8') ?></td>
</tr> </tr>
</table> </table>
@ -158,12 +163,12 @@ header('Pragma: no-cache');
} else { } else {
?> ?>
<form action="stats.php?op=login" method="POST"> <form action="stats.php?op=login" method="POST">
<h3>Login</h3> <h3>登录</h3>
<input type="password" name="password" placeholder="Password" value=""/> <input type="password" name="password" placeholder="密码" value=""/>
<input type="submit" value="Login" /> <input type="submit" value="登录" />
</form> </form>
<?php <?php
} }
?> ?>
</body> </body>
</html> </html>

View file

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

View file

@ -49,7 +49,7 @@ function Speedtest() {
this._settings = {}; //settings for the speed test worker 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 this._state = 0; //0=adding settings, 1=adding servers, 2=server selection done, 3=test running, 4=done
console.log( 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"
); );
} }