Start using new HTML5/CSS code.

This commit is contained in:
Darren 'Tadgy' Austin 2024-08-10 23:06:12 +01:00
commit cb4688d7a6
23 changed files with 650 additions and 616 deletions

1
html/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/speedtest.git/

1
html/backend/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/getIP_ipInfo_apikey.php

Binary file not shown.

BIN
html/backend/geoip2.phar Normal file

Binary file not shown.

View file

@ -2,7 +2,7 @@
/*
* This script detects the client's IP address and fetches ISP info from ipinfo.io/
* Output from this script is a JSON string composed of 2 objects: a string called processedString which contains the combined IP, ISP, Country and distance as it can be presented to the user; and an object called rawIspInfo which contains the raw data from ipinfo.io (will be empty if isp detection is disabled).
* Output from this script is a JSON string composed of 2 objects: a string called processedString which contains the combined IP, ISP, Country and distance as it can be presented to the user; and an object called rawIspInfo which contains the raw data from ipinfo.io (or an empty string if isp detection is disabled or if it failed).
* Client side, the output of this script can be treated as JSON or as regular text. If the output is regular text, it will be shown to the user as is.
*/
@ -10,399 +10,194 @@ error_reporting(0);
define('API_KEY_FILE', 'getIP_ipInfo_apikey.php');
define('SERVER_LOCATION_CACHE_FILE', 'getIP_serverLocation.php');
define('OFFLINE_IPINFO_DB_FILE', 'country_asn.mmdb');
require_once 'getIP_util.php';
/**
* @param string $ip
*
* @return string|null
*/
function getLocalOrPrivateIpInfo($ip)
{
function getLocalOrPrivateIpInfo($ip){
// ::1/128 is the only localhost ipv6 address. there are no others, no need to strpos this
if ('::1' === $ip) {
return 'localhost IPv6 access';
}
// simplified IPv6 link-local address (should match fe80::/10)
if (stripos($ip, 'fe80:') === 0) {
return 'link-local IPv6 access';
}
// fc00::/7 Unique Local IPv6 Unicast Addresses
if (preg_match('/^(fc|fd)([0-9a-f]{0,4}:){1,7}[0-9a-f]{1,4}$/i', $ip) === 1) {
return 'ULA IPv6 access';
}
// anything within the 127/8 range is localhost ipv4, the ip must start with 127.0
if (strpos($ip, '127.') === 0) {
return 'localhost IPv4 access';
}
// 10/8 private IPv4
if (strpos($ip, '10.') === 0) {
return 'private IPv4 access';
}
// 172.16/12 private IPv4
if (preg_match('/^172\.(1[6-9]|2\d|3[01])\./', $ip) === 1) {
return 'private IPv4 access';
}
// 192.168/16 private IPv4
if (strpos($ip, '192.168.') === 0) {
return 'private IPv4 access';
}
// IPv4 link-local
if (strpos($ip, '169.254.') === 0) {
return 'link-local IPv4 access';
}
return null;
}
/**
* @return string
*/
function getIpInfoTokenString()
{
if (
!file_exists(API_KEY_FILE)
|| !is_readable(API_KEY_FILE)
) {
return '';
function getIspInfo_ipinfoApi($ip){
if (!file_exists(API_KEY_FILE) || !is_readable(API_KEY_FILE)){
return null;
}
require API_KEY_FILE;
if (empty($IPINFO_APIKEY)) {
return '';
if(empty($IPINFO_APIKEY)){
return null;
}
return '?token=' . $IPINFO_APIKEY;
}
/**
* @param string $ip
*
* @return array|null
*/
function getIspInfo($ip)
{
$json = file_get_contents('https://ipinfo.io/' . $ip . '/json' . getIpInfoTokenString());
$json = file_get_contents('https://ipinfo.io/' . $ip . '/json?token=' . $IPINFO_APIKEY);
if (!is_string($json)) {
return null;
}
$data = json_decode($json, true);
if (!is_array($data)) {
return null;
}
return $data;
}
/**
* @param array|null $rawIspInfo
*
* @return string
*/
function getIsp($rawIspInfo)
{
if (is_array($rawIspInfo)) {
/* variant with no token
has json like:
{
"ip": "xxx.xxx.xxx.xxx",
"hostname": "example.com",
"city": "Vienna",
"region": "Vienna",
"country": "AT",
"loc": "48.2085,16.3721",
"org": "ASxxxx T-Mobile Austria GmbH",
"postal": "nnnn",
"timezone": "Europe/Vienna",
"readme": "https://ipinfo.io/missingauth"
$isp=null;
//ISP name, if present, is either in org or asn.name
if (array_key_exists('org', $data) && is_string($data['org']) && !empty($data['org'])) {
// Remove AS##### from ISP name, if present
$isp = preg_replace('/AS\\d+\\s/', '', $data['org']);
} elseif (array_key_exists('asn', $data) && is_array($data['asn']) && !empty($data['asn']) && array_key_exists('name', $data['asn']) && is_string($data['asn']['name'])) {
$isp = $data['asn']['name'];
} else{
return null;
}
$country=null;
if(array_key_exists('country',$data) && is_string($data['country'])){
$country = $data['country'];
}
//If requested by the client (and we have the required information), calculate the distance
$distance=null;
if(isset($_GET['distance']) && ($_GET['distance']==='mi' || $_GET['distance']==='km') && array_key_exists('loc', $data) && is_string($data['loc'])){
$unit = $_GET['distance'];
$clientLoc = $data['loc'];
$serverLoc = null;
if (file_exists(SERVER_LOCATION_CACHE_FILE) && is_readable(SERVER_LOCATION_CACHE_FILE)) {
require SERVER_LOCATION_CACHE_FILE;
}
*/
if (
array_key_exists('org', $rawIspInfo)
&& is_string($rawIspInfo['org'])
&& !empty($rawIspInfo['org'])
) {
// Remove AS##### from ISP name, if present
return preg_replace('/AS\\d+\\s/', '', $rawIspInfo['org']);
}
/*
variant with valid token has json:
{
"ip": "xxx.xxx.xxx.xxx",
"hostname": "example.com",
"city": "Vienna",
"region": "Vienna",
"country": "AT",
"loc": "48.2085,16.3721",
"postal": "1010",
"timezone": "Europe/Vienna",
"asn": {
"asn": "ASxxxx",
"name": "T-Mobile Austria GmbH",
"domain": "t-mobile.at",
"route": "xxx.xxx.xxx.xxx/xx",
"type": "isp"
},
"company": {
"name": "XX",
"domain": "example.com",
"type": "isp"
},
"privacy": {
"vpn": true,
"proxy": false,
"tor": false,
"relay": false,
"hosting": false,
"service": ""
},
"abuse": {
"address": "...",
"country": "AT",
"email": "abuse@example.com",
"name": "XXX",
"network": "xxx.xxx.xxx.xxx-xxx.xxx.xxx.xxx",
"phone": ""
},
"domains": {
"total": 0,
"domains": [
]
if (!is_string($serverLoc) || empty($serverLoc)) {
$json = file_get_contents('https://ipinfo.io/json?token=' . $IPINFO_APIKEY);
if (!is_string($json)) {
return null;
}
$sdata = json_decode($json, true);
if (!is_array($sdata) || !array_key_exists('loc', $sdata) || !is_string($sdata['loc']) || empty($sdata['loc'])) {
return null;
}
*/
if (
array_key_exists('asn', $rawIspInfo)
&& is_array($rawIspInfo['asn'])
&& !empty($rawIspInfo['asn'])
&& array_key_exists('name', $rawIspInfo['asn'])
&& is_string($rawIspInfo['asn']['name'])
) {
// Remove AS##### from ISP name, if present
return $rawIspInfo['asn']['name'];
$serverLoc = $sdata['loc'];
file_put_contents(SERVER_LOCATION_CACHE_FILE, "<?php\n\n\$serverLoc = '" . addslashes($serverLoc) . "';\n");
}
list($clientLatitude, $clientLongitude) = explode(',', $clientLoc);
list($serverLatitude, $serverLongitude) = explode(',', $serverLoc);
//distance calculation adapted from http://www.codexworld.com
$rad = M_PI / 180;
$dist = acos(sin($clientLatitude * $rad) * sin($serverLatitude * $rad) + cos($clientLatitude * $rad) * cos($serverLatitude * $rad) * cos(($clientLongitude - $serverLongitude) * $rad)) / $rad * 60 * 1.853;
if ($unit === 'mi') {
$dist /= 1.609344;
$dist = round($dist, -1);
if ($dist < 15) {
$dist = '<15';
}
$distance = $dist . ' mi';
}elseif ($unit === 'km') {
$dist = round($dist, -1);
if ($dist < 20) {
$dist = '<20';
}
$distance = $dist . ' km';
}
}
return 'Unknown ISP';
}
/**
* @return string|null
*/
function getServerLocation()
{
$serverLoc = null;
if (
file_exists(SERVER_LOCATION_CACHE_FILE)
&& is_readable(SERVER_LOCATION_CACHE_FILE)
) {
require SERVER_LOCATION_CACHE_FILE;
$processedString=$ip.' - '.$isp;
if(is_string($country)){
$processedString.=', '.$country;
}
if (is_string($serverLoc) && !empty($serverLoc)) {
return $serverLoc;
if(is_string($distance)){
$processedString.=' ('.$distance.')';
}
$json = file_get_contents('https://ipinfo.io/json' . getIpInfoTokenString());
if (!is_string($json)) {
return null;
}
$details = json_decode($json, true);
if (
!is_array($details)
|| !array_key_exists('loc', $details)
|| !is_string($details['loc'])
|| empty($details['loc'])
) {
return null;
}
$serverLoc = $details['loc'];
$cacheData = "<?php\n\n\$serverLoc = '" . addslashes($serverLoc) . "';\n";
file_put_contents(SERVER_LOCATION_CACHE_FILE, $cacheData);
return $serverLoc;
}
/**
* Optimized algorithm from http://www.codexworld.com
*
* @param float $latitudeFrom
* @param float $longitudeFrom
* @param float $latitudeTo
* @param float $longitudeTo
*
* @return float [km]
*/
function distance(
$latitudeFrom,
$longitudeFrom,
$latitudeTo,
$longitudeTo
) {
$rad = M_PI / 180;
$theta = $longitudeFrom - $longitudeTo;
$dist = sin($latitudeFrom * $rad)
* sin($latitudeTo * $rad)
+ cos($latitudeFrom * $rad)
* cos($latitudeTo * $rad)
* cos($theta * $rad);
return acos($dist) / $rad * 60 * 1.853;
}
/**
* @param array|null $rawIspInfo
*
* @return string|null
*/
function getDistance($rawIspInfo)
{
if (
!is_array($rawIspInfo)
|| !array_key_exists('loc', $rawIspInfo)
|| !isset($_GET['distance'])
|| !in_array($_GET['distance'], ['mi', 'km'], true)
) {
return null;
}
$unit = $_GET['distance'];
$clientLocation = $rawIspInfo['loc'];
$serverLocation = getServerLocation();
if (!is_string($serverLocation)) {
return null;
}
return calculateDistance(
$serverLocation,
$clientLocation,
$unit
);
}
/**
* @param string $clientLocation
* @param string $serverLocation
* @param string $unit
*
* @return string
*/
function calculateDistance($clientLocation, $serverLocation, $unit)
{
list($clientLatitude, $clientLongitude) = explode(',', $clientLocation);
list($serverLatitude, $serverLongitude) = explode(',', $serverLocation);
$dist = distance(
$clientLatitude,
$clientLongitude,
$serverLatitude,
$serverLongitude
);
if ('mi' === $unit) {
$dist /= 1.609344;
$dist = round($dist, -1);
if ($dist < 15) {
$dist = '<15';
}
return $dist . ' mi';
}
if ('km' === $unit) {
$dist = round($dist, -1);
if ($dist < 20) {
$dist = '<20';
}
return $dist . ' km';
}
return null;
}
/**
* @return void
*/
function sendHeaders()
{
header('Content-Type: application/json; charset=utf-8');
if (isset($_GET['cors'])) {
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
}
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0, s-maxage=0');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
}
/**
* @param string $ip
* @param string|null $ipInfo
* @param string|null $distance
* @param array|null $rawIspInfo
*
* @return void
*/
function sendResponse(
$ip,
$ipInfo = null,
$distance = null,
$rawIspInfo = null
) {
$processedString = $ip;
if (is_string($ipInfo)) {
$processedString .= ' - ' . $ipInfo;
}
if (
is_array($rawIspInfo)
&& array_key_exists('country', $rawIspInfo)
) {
$processedString .= ', ' . $rawIspInfo['country'];
}
if (is_string($distance)) {
$processedString .= ' (' . $distance . ')';
}
sendHeaders();
echo json_encode([
return json_encode([
'processedString' => $processedString,
'rawIspInfo' => $rawIspInfo ?: '',
'rawIspInfo' => $data ?: '',
]);
}
if (PHP_MAJOR_VERSION >= 8){
require_once("geoip2.phar");
}
function getIspInfo_ipinfoOfflineDb($ip){
if (!file_exists(OFFLINE_IPINFO_DB_FILE) || !is_readable(OFFLINE_IPINFO_DB_FILE)){
return null;
}
$reader = new MaxMind\Db\Reader(OFFLINE_IPINFO_DB_FILE);
$data = $reader->get($ip);
if(!is_array($data)){
return null;
}
$processedString = $ip.' - ' . $data['as_name'] . ', ' . $data['country_name'];
return json_encode([
'processedString' => $processedString,
'rawIspInfo' => $data ?: '',
]);
}
function formatResponse_simple($ip,$ispName=null){
$processedString=$ip;
if(is_string($ispName)){
$processedString.=' - '.$ispName;
}
return json_encode([
'processedString' => $processedString,
'rawIspInfo' => '',
]);
}
header('Content-Type: application/json; charset=utf-8');
if (isset($_GET['cors'])) {
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
}
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0, s-maxage=0');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
$ip = getClientIp();
$localIpInfo = getLocalOrPrivateIpInfo($ip);
// local ip, no need to fetch further information
if (is_string($localIpInfo)) {
sendResponse($ip, $localIpInfo);
exit;
//if the user requested the ISP info, we first try to fetch it using ipinfo.io (if there is no api key set it fails without sending data, it can also fail because of rate limiting or invalid responses), then we try with the offline db, if that also fails (or if ISP info was not requested) we just respond with the IP address
if(isset($_GET['isp'])){
$localIpInfo = getLocalOrPrivateIpInfo($ip);
//local ip, no need to fetch further information
if (is_string($localIpInfo)) {
echo formatResponse_simple($ip,$localIpInfo);
}else{
//ipinfo API and offline db require PHP 8 or newer
if (PHP_MAJOR_VERSION >= 8){
$r=getIspInfo_ipinfoApi($ip);
if(!is_null($r)){
echo $r;
}else{
$r=getIspInfo_ipinfoOfflineDb($ip);
if(!is_null($r)){
echo $r;
}else{
echo formatResponse_simple($ip);
}
}
}else{
echo formatResponse_simple($ip);
}
}
}else{
echo formatResponse_simple($ip);
}
if (!isset($_GET['isp'])) {
sendResponse($ip);
exit;
}
$rawIspInfo = getIspInfo($ip);
$isp = getIsp($rawIspInfo);
$distance = getDistance($rawIspInfo);
sendResponse($ip, $isp, $distance, $rawIspInfo);

View file

@ -1,4 +0,0 @@
<?php
// put your token between the quotes if you have one
$IPINFO_APIKEY = '';

View file

@ -17,4 +17,3 @@ function getClientIp() {
return preg_replace('/^::ffff:/', '', $ip);
}

BIN
html/circuit-dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
html/circuit-light.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View file

@ -1,126 +1,235 @@
body{
text-align: center;
a:link {
color: #4255ff;
text-decoration: none;
}
div.ip{
color: #ffffff !important;
a:visited {
color: #943cc3;
text-decoration: none;
}
div.meterText:empty:before{
color: #888888 !important;
content: "0.00";
a:hover {
text-decoration: underline;
}
div.meterText{
position: absolute;
bottom: 1.5em;
left: 0;
width: 100%;
font-size: 2.5em;
z-index: 9;
body {
background-color: #000000;
background-image: url("/circuit-dark.png");
color: #aeaeae;
padding-top: 15px;
}
div.testArea{
display: inline-block;
width: 20em;
height: 9em;
position: relative;
box-sizing: border-box;
hr {
background-color: #888888;
border: 0;
color: #888888;
height: 2px;
}
div.progressText{
margin-bottom: 2px;
img {
border: 0;
}
.bold {
font-weight: bold;
}
div.testGroup{
display: inline-block;
.box {
background: #060606;
border: 2px solid #aaaaaa;
box-shadow: 10px 10px 10px -5px rgba(128,128,128,0.5);
overflow-x: auto;
}
div.testName{
position: absolute;
top: 0.1em;
left: 0;
width: 100%;
font-size: 1.4em;
color: #ffffff !important;
z-index:9;
.boxmargins {
margin-bottom: 10px;
}
div.unit{
position: absolute;
bottom: 2em;
left: 0;
width: 100%;
color: #ffffff !important;
z-index:9;
.boxpadding {
padding-bottom: 10px;
padding-left: 20px;
padding-right: 20px;
padding-top: 10px;
}
html,body{
border: none;
padding: 0;
.donatebutton {
margin-left: 100px;
margin-right: 100px;
}
#dlText{
color: #4255ff;
.heading {
font-size: 200%;
}
#pingText,#jitText{
color: #4255ff;
.metertext {
font-size: 200%;
}
#progress{
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 0%;
transition: width 2s;
background-color: #4255ff;
.metertext:empty:before {
content: "0.00";
}
#progressBar{
width: 60%;
height: 0.3em;
background-color: #060606;
position: relative;
.notice {
display: block;
margin: 0 auto;
border: 2px solid #ffffff;
margin-left: auto;
margin-bottom: 25px;
margin-right: auto;
text-align: center;
width: 70%;
}
#startStopBtn{
display: inline-block;
margin: 0 auto;
color: #4255ff;
.sponsor {
margin-top: 15px;
margin-bottom: 15px;
}
.subheading {
font-size: 125%;
}
#copyright {
font-size: 10px;
text-align: center;
}
#donatebuttons {
display: flex;
flex-wrap: wrap;
justify-content: center;
margin-bottom: 10px;
margin-top: 20px;
}
#headingbox {
margin-left: auto;
margin-right: auto;
width: fit-content;
}
#headingtext {
margin-bottom: 5px;
margin-left: 5px;
margin-right: 5px;
margin-top: 5px;
text-align: center;
}
#ipinfo {
text-align: center;
}
#logo {
display: flex;
justify-content: center;
margin-bottom: 30px;
}
#page {
margin-left: auto;
margin-right: auto;
width: 90%;
}
#progress {
background-color: #4255ff;
height: 100%;
position: absolute;
transition: width 2s;
width: 0%;
}
#progressbar {
background-color: #060606;
border: 2px solid #aaaaaa;
height: 8px;
margin-bottom: 5px;
margin-right: auto;
margin-left: auto;
position: relative;
width: 600px;
}
#progresstext {
margin-bottom: 5px;
text-align: center;
}
#startstopbutton {
#margin: 0 auto;
background-color: #060606;
border: 2px solid #4255ff;
/* border-radius: 0.3em; */
transition: all 0.3s;
box-sizing: border-box;
width: 8em;
height: 3em;
margin-bottom: 2em;
line-height: 2.7em;
color: #4255ff;
cursor: pointer;
/* box-shadow: 0 0 0 rgba(0,0,0,0.1), inset 0 0 0 rgba(0,0,0,0.1); */
height: 40px;
line-height: 36px;
transition: all 0.3s;
width: 150px;
margin-bottom: 30px;
margin-right: auto;
margin-left: auto;
text-align: center;
}
#startStopBtn:before{
content: "Start";
#startstopbutton:before {
content: "Start Test";
}
#startStopBtn.running{
#startstopbutton.running {
background-color:#4255ff;
border-color:#ffffff;
color:#ffffff;
border-color:#aaaaaa;
color:#aaaaaa;
}
#startStopBtn.running:before{
#startstopbutton.running:before {
content: "Abort";
}
#test{
margin-top: 2em;
margin-bottom: 2em;
#testbox {
margin-left: auto;
margin-right: auto;
padding-left: 75px;
padding-right: 75px;
width: fit-content;
}
#tests {
column-gap: 150px;
display: grid;
grid-template-columns: auto auto auto;
justify-content: center;
margin-bottom: 30px;
text-align: center;
}
#theme {
column-gap: 50px;
display: grid;
grid-template-columns: auto auto auto;
}
#themetoggle {
align-self: end;
display: flex;
height: 25px;
margin-left: auto;
margin-right: 0;
max-height: 25px;
text-align: right;
}
#themetoggleimg {
height: 15px;
margin-right: 5px;
vertical-align: middle;
}
#themetoggletext {
align-content: center;
color: #888888;
font-size: 15px;
margin-left: 5px;
margin-right: 5px;
}

View file

@ -1,89 +1,136 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<?php
if ($_COOKIE['theme'] == "light") {
$light = true;
} else {
$light = false;
}
?>
<!DOCTYPE html>
<html>
<head>
<?php if ($light) { ?>
<link rel="stylesheet" href="//slackware.uk/html/light.css" type="text/css">
<link rel="stylesheet" href="/light.css" type="text/css">
<?php if ($_COOKIE['theme'] == "light") { ?>
<link rel="stylesheet" href="/light.css" type="text/css">
<?php } else { ?>
<link rel="stylesheet" href="https://slackware.uk/html/dark.css" type="text/css">
<link rel="stylesheet" href="/dark.css" type="text/css">
<link rel="stylesheet" href="/dark.css" type="text/css">
<?php } ?>
<link rel="shortcut icon" href="/favicon.ico">
<meta charset="UTF-8">
<meta name="author" content="Darren 'Tadgy' Austin">
<meta name="description" content="Slackware UK Speedtest">
<meta name="keywords" content="Slackware UK Speedtest">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no">
<meta name="description" content="Slackware UK download speedtest">
<meta name="keywords" content="Slackware UK, speedtest, speed">
<title>Slackware UK: Speedtest</title>
<script type="text/javascript" src="speedtest.js"></script>
<script type="text/javascript" src="init.js"></script>
<script type="text/javascript" src="/speedtest.js"></script>
<script type="text/javascript">
var s=new Speedtest();
s.setParameter("test_order","IP_D"); // Only get IP, and do ping and download tests
s.setParameter("time_auto",true); // Use a fixed duration for tests
s.setParameter("time_dl_max",10); // 10 seconds for the download test
function I(id) {
return document.getElementById(id);
}
function startStop() {
if(s.getState() == 3) {
s.abort();
} else {
s.start();
I("startstopbutton").className="running";
}
}
function initUI() {
I("downloadtext").textContent="";
I("pingtext").textContent="";
I("jittertext").textContent="";
I("ip").textContent="";
}
s.onupdate=function(data) {
I("ip").textContent=data.clientIp;
I("downloadtext").textContent=(data.testState == 1 && data.dlStatus == 0) ? "..." : data.dlStatus;
I("pingtext").textContent=data.pingStatus;
I("jittertext").textContent=data.jitterStatus;
var prog=(Number(data.dlProgress)*2+Number(data.pingProgress))/3;
I("progress").style.width=(100*prog)+"%";
}
s.onend=function(aborted) {
I("startstopbutton").className="";
if(aborted) {
initUI();
}
}
</script>
</head>
<body>
<?php if ($light) { ?>
<p><a href="//slackware.uk/" title="Slackware UK"><img src="//slackware.uk/html/slackwareuk-black.png" title="Slackware UK" alt="Slackware UK Logo" border=0 align=center></a></p>
<?php } else { ?>
<p><a href="//slackware.uk/" title="Slackware UK"><img src="//slackware.uk/html/slackwareuk-white.png" title="Slackware UK" alt="Slackware UK Logo" border=0 align=center></a></p>
<?php } ?>
<p>
<b>is kindly sponsored by:</b>
<div align="center">
<a href="//mailg.ukservers.com/c/eJxVjDkOwyAQAF8DJYLlLijS-B8LbGTLdhKBE5TfhzajKUdTk0fnNN8SSADplVETAGFUVqWCCmBiDETMyPfeqX2odVGeJ18TeQXag9W2uoAaCLyNeC9GZp-drfxI63W9OtM3Bst0jCH-Jy31b8d6bo_57weWfWCjGf0AmK0uIA" title="UK Servers"><img src="//slackware.uk/html/ukservers.png" title="UK Servers" alt="UK Servers Logo" border="0" align="center" hspace="50"></a>
<?php if ($light) { ?>
<a href="//www.uk2.net/" title="UK2"><img src="//slackware.uk/html/uk2-black.png" title="UK2" alt="UK2 Logo" border="0" align="center" hspace="50"></a>
<div id="page">
<div id="logo">
<?php if ($_COOKIE['theme'] == "light") { ?>
<a href="/" title="Slackware UK"><img src="/slackwareuk-black.png" title="Slackware UK" alt="Slackware UK Logo"></a>
<?php } else { ?>
<a href="//www.uk2.net/" title="UK2"><img src="//slackware.uk/html/uk2-white.png" title="UK2" alt="UK2 Logo" border="0" align="center" hspace="50"></a>
<a href="/" title="Slackware UK"><img src="/slackwareuk-white.png" title="Slackware UK" alt="Slackware UK Logo"></a>
<?php } ?>
</div>
<br>
<b>Please take a moment to visit the sponsors using the links above!</b>
</p><br>
<center>
<table class="header">
<tr align="center">
<td>
<b class="heading">Slackware UK Speedtest</b><br><br>
<hr>
<div class="notice">
<span class="heading bold">Patronage & Donations</span><br>
If you use the Slackware UK services on a regular basis, and would like to contribute to running costs, make a continuing patronage (and receive special benefits), or make a one off PayPal payment, please use one of the following buttons:
<div id="donatebuttons">
<?php if ($_COOKIE['theme'] == "light") { ?>
<a class="donatebutton" href="https://www.patreon.com/slackwareUK" title="Patreon"><img src="/patreon-black.png" title="Patreon" alt="Patreon Logo"></a>
<a class="donatebutton" href="https://paypal.me/DonateToSlackwareUK" title="PayPal"><img src="/paypal-black.png" title="PayPal" alt="PayPal Logo"></a>
<?php } else { ?>
<a class="donatebutton" href="https://www.patreon.com/slackwareUK" title="Patreon"><img src="/patreon-white.png" title="Patreon" alt="Patreon Logo"></a>
<a class="donatebutton" href="https://paypal.me/DonateToSlackwareUK" title="PayPal"><img src="/paypal-white.png" title="PayPal" alt="PayPal Logo"></a>
<?php } ?>
</div>
All <a href="//slackware.uk/html/donors.php" title="Donors">donations</a> will be gratefully received - thank you!
</div>
<div id="theme">
<div></div>
<div></div>
<div class="box boxmargins" id="themetoggle">
<span id="themetoggletext">Toggle&nbsp;theme:</span><a href="/toggletheme.php" title="Toggle Theme"><img id="themetoggleimg" src="/toggletheme.png" title="Toggle Theme" alt="Toggle Theme Button"></a>
</div>
</div>
<div class="box boxmargins" id="headingbox">
<div id="headingtext">
<span class="heading bold">Slackware UK Speedtest</span><br>
<span class="subheading">
On this page you can test the speed at which you<br>
can download data from the Slackware UK server.
</td>
</tr>
</table>
</center>
<div id="test">
<div class="testGroup">
<div class="testArea">
<div class="testName">Ping</div>
<div id="pingText" class="meterText"></div>
<div class="unit">ms</div>
</div>
<div class="testArea">
<div class="testName">Jitter</div>
<div id="jitText" class="meterText"></div>
<div class="unit">ms</div>
</div>
<div class="testArea">
<div class="testName">Download</div>
<div id="dlText" class="meterText"></div>
<div class="unit">Mbit/s</div>
</span>
</div>
</div>
<div class="ip" id="ipArea">
Your IP information: <span id="ip"></span>
<div class="box boxmargins boxpadding" id="testbox">
<div id="tests">
<div>
<div class="subheading bold">Ping</div>
<div id="pingtext" class="metertext"></div>
<div>ms</div>
</div>
<div>
<div class="subheading bold">Jitter</div>
<div id="jittertext" class="metertext"></div>
<div>ms</div>
</div>
<div>
<div class="subheading bold">Download</div>
<div id="downloadtext" class="metertext"></div>
<div>Mbit/sec</div>
</div>
</div>
<div id="startstopbutton" onclick="startStop()"></div>
<div id="ipinfo">
Your IP information: <span id="ip"></span>
</div>
</div>
<br>
<div class="bold" id="progresstext">Test progress</div>
<div id="progressbar">
<div id="progress"></div>
</div>
<div id="copyright">
Slackware UK logo, design and code &copy; Darren 'Tadgy' Austin<br>
Speedtest code by <a href="https://github.com/librespeed/speedtest.git" title="LibreSpeed">LibreSpeed</a>
</div>
<script type="text/javascript">
initUI();
</script>
</div>
<div id="startStopBtn" onclick="startStop()"></div>
<div class="progressText">Test progress...</div>
<div id="progressBar">
<div id="progress"></div>
</div>
<script type="text/javascript">
initUI();
</script>
</body>
</html>

View file

@ -1,43 +0,0 @@
var s=new Speedtest(); //create speedtest object
s.setParameter("test_order","IP_D"); //we only want download test
s.setParameter("time_auto",true); //fixed duration for tests
s.setParameter("time_dl_max",10); //10 seconds for the download test
s.onupdate=function(data){
I("ip").textContent=data.clientIp;
I("dlText").textContent=(data.testState==1&&data.dlStatus==0)?"...":data.dlStatus;
I("pingText").textContent=data.pingStatus;
I("jitText").textContent=data.jitterStatus;
var prog=(Number(data.dlProgress)*2+Number(data.pingProgress))/3;
I("progress").style.width=(100*prog)+"%";
}
s.onend=function(aborted){
I("startStopBtn").className=""; //show start button again
if(aborted){
initUI();
}
}
function startStop(){
if(s.getState()==3){
//speedtest is running, abort
s.abort();
}else{
//test is not running, begin
s.start();
I("startStopBtn").className="running";
}
}
function initUI(){
I("dlText").textContent="";
I("pingText").textContent="";
I("jitText").textContent="";
I("ip").textContent="";
}
function I(id){
return document.getElementById(id);
}

View file

@ -1,126 +1,235 @@
body{
text-align: center;
a:link {
color: #2c199c;
text-decoration: none;
}
div.ip{
color: #000000 !important;
a:visited {
color: #943cc3;
text-decoration: none;
}
div.meterText:empty:before{
color: #070707 !important;
content: "0.00";
a:hover {
text-decoration: underline;
}
div.meterText{
position: absolute;
bottom: 1.5em;
left: 0;
width: 100%;
font-size: 2.5em;
z-index: 9;
body {
background-color: #ffffff;
background-image: url("/circuit-light.png");
color: #000000;
padding-top: 15px;
}
div.testArea{
display: inline-block;
width: 20em;
height: 9em;
position: relative;
box-sizing: border-box;
hr {
background-color: #070707;
border: 0;
color: #070707;
height: 2px;
}
div.progressText{
margin-bottom: 2px;
img {
border: 0;
}
.bold {
font-weight: bold;
}
div.testGroup{
display: inline-block;
.box {
background: #f0f0f0;
border: 2px solid #070707;
box-shadow: 10px 10px 10px -5px rgba(0,0,0,0.5);
overflow-x: auto;
}
div.testName{
position: absolute;
top: 0.1em;
left: 0;
width: 100%;
font-size: 1.4em;
color: #000000 !important;
z-index:9;
.boxmargins {
margin-bottom: 10px;
}
div.unit{
position: absolute;
bottom: 2em;
left: 0;
width: 100%;
color: #000000 !important;
z-index:9;
.boxpadding {
padding-bottom: 10px;
padding-left: 20px;
padding-right: 20px;
padding-top: 10px;
}
html,body{
border: none;
padding: 0;
.donatebutton {
margin-left: 100px;
margin-right: 100px;
}
#dlText{
color: #2c199c;
.heading {
font-size: 200%;
}
#pingText,#jitText{
color: #2c199c;
.metertext {
font-size: 200%;
}
#progress{
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 0%;
transition: width 2s;
background-color: #2c199c;
.metertext:empty:before {
content: "0.00";
}
#progressBar{
width: 60%;
height: 0.3em;
background-color: #f0f0f0;
position: relative;
.notice {
display: block;
margin: 0 auto;
border: 2px solid #000000;
margin-left: auto;
margin-bottom: 25px;
margin-right: auto;
text-align: center;
width: 70%;
}
#startStopBtn{
display: inline-block;
margin: 0 auto;
color: #2c199c;
.sponsor {
margin-top: 15px;
margin-bottom: 15px;
}
.subheading {
font-size: 125%;
}
#copyright {
font-size: 10px;
text-align: center;
}
#donatebuttons {
display: flex;
flex-wrap: wrap;
justify-content: center;
margin-bottom: 10px;
margin-top: 20px;
}
#headingbox {
margin-left: auto;
margin-right: auto;
width: fit-content;
}
#headingtext {
margin-bottom: 5px;
margin-left: 5px;
margin-right: 5px;
margin-top: 5px;
text-align: center;
}
#ipinfo {
text-align: center;
}
#logo {
display: flex;
justify-content: center;
margin-bottom: 30px;
}
#page {
margin-left: auto;
margin-right: auto;
width: 90%;
}
#progress {
background-color: #2c199c;
height: 100%;
position: absolute;
transition: width 2s;
width: 0%;
}
#progressbar {
background-color: #f0f0f0;
border: 2px solid #070707;
height: 8px;
margin-bottom: 5px;
margin-right: auto;
margin-left: auto;
position: relative;
width: 600px;
}
#progresstext {
margin-bottom: 5px;
text-align: center;
}
#startstopbutton {
#margin: 0 auto;
background-color: #f0f0f0;
border: 2px solid #2c199c;
/* border-radius: 0.3em; */
transition: all 0.3s;
box-sizing: border-box;
width: 8em;
height: 3em;
margin-bottom: 2em;
line-height: 2.7em;
color: #2c199c;
cursor: pointer;
/* box-shadow: 0 0 0 rgba(0,0,0,0.1), inset 0 0 0 rgba(0,0,0,0.1); */
height: 40px;
line-height: 36px;
transition: all 0.3s;
width: 150px;
margin-bottom: 30px;
margin-right: auto;
margin-left: auto;
text-align: center;
}
#startStopBtn:before{
content: "Start";
#startstopbutton:before {
content: "Start Test";
}
#startStopBtn.running{
#startstopbutton.running {
background-color:#2c199c;
border-color:#000000;
color:#ffffff;
border-color:#070707;
color:#f0f0f0;
}
#startStopBtn.running:before{
#startstopbutton.running:before {
content: "Abort";
}
#test{
margin-top: 2em;
margin-bottom: 2em;
#testbox {
margin-left: auto;
margin-right: auto;
padding-left: 75px;
padding-right: 75px;
width: fit-content;
}
#tests {
column-gap: 150px;
display: grid;
grid-template-columns: auto auto auto;
justify-content: center;
margin-bottom: 30px;
text-align: center;
}
#theme {
column-gap: 50px;
display: grid;
grid-template-columns: auto auto auto;
}
#themetoggle {
align-self: end;
display: flex;
height: 25px;
margin-left: auto;
margin-right: 0;
max-height: 25px;
text-align: right;
}
#themetoggleimg {
height: 15px;
margin-right: 5px;
vertical-align: middle;
}
#themetoggletext {
align-content: center;
color: #070707;
font-size: 15px;
margin-left: 5px;
margin-right: 5px;
}

BIN
html/patreon-black.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
html/patreon-white.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
html/paypal-black.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
html/paypal-white.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
html/slackwareuk-black.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
html/slackwareuk-white.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View file

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

20
html/toggletheme.php Normal file
View file

@ -0,0 +1,20 @@
<?php
$cookie_data = array(
"expires" => mktime (23, 59, 59, 12, 31, 2069),
"domain" => ".slackware.uk",
"path" => "/",
"httponly" => true,
"samesite" => "Lax"
);
if ($_COOKIE['theme'] != "light") {
$theme = "light";
} else {
$theme = "dark";
}
setcookie ("theme", $theme, $cookie_data);
if (isset ($_SERVER['HTTP_REFERER'])) {
header ("Location: " . $_SERVER['HTTP_REFERER'], true, 302);
} else {
header ("Location: /", true, 302);
}
?>

BIN
html/toggletheme.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
html/ukservers.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB