Docker更改为中文,并且可以使用TZ环境变量
This commit is contained in:
parent
80cf39987a
commit
0b64f64b2c
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"githubPullRequests.ignoredPullRequestBranches": [
|
||||||
|
"master"
|
||||||
|
]
|
||||||
|
}
|
113
README.md
113
README.md
|
@ -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
9
doc.md
|
@ -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:
|
||||||
|
|
138
doc_docker.md
138
doc_docker.md
|
@ -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.
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
68
index.html
68
index.html
|
@ -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>
|
||||||
|
|
|
@ -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
BIN
results/simhei.ttf
Normal file
Binary file not shown.
|
@ -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,9 +163,9 @@ 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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
@ -211,6 +211,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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue