Verified Commit 2ed04f2e authored by Bixilon's avatar Bixilon

Initial commit

parents
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/speedtest-v3.iml" filepath="$PROJECT_DIR$/.idea/speedtest-v3.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WebResourcesPaths">
<contentEntries>
<entry url="file://$PROJECT_DIR$">
<entryData>
<resourceRoots>
<path value="file://$PROJECT_DIR$/html" />
</resourceRoots>
</entryData>
</entry>
</contentEntries>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="e05b79ac-4742-48af-8b00-f7f616ac4962" name="Default Changelist" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ComposerSettings">
<execution />
</component>
<component name="GitToolBoxStore">
<option name="projectConfigVersion" value="2" />
</component>
<component name="ProjectId" id="1jh2Y1dafntEQjVHwfq809Cq0Sv" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/html" />
<property name="vue.rearranger.settings.migration" value="true" />
</component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$" />
<recent name="$PROJECT_DIR$/app/includes" />
</key>
<key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/html" />
</key>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="e05b79ac-4742-48af-8b00-f7f616ac4962" name="Default Changelist" comment="" />
<created>1604242046733</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1604242046733</updated>
<workItem from="1604242047756" duration="1237000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="WindowStateProjectService">
<state x="556" y="1255" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1604242944302">
<screen x="0" y="1050" width="1920" height="1080" />
</state>
<state x="556" y="1255" key="#com.intellij.execution.impl.EditConfigurationsDialog/0.40.1680.1010/0.1050.1920.1080/1680.26.1280.1024@0.1050.1920.1080" timestamp="1604242944302" />
<state x="798" y="1516" key="NewPhpFileDialog" timestamp="1604242319849">
<screen x="0" y="1050" width="1920" height="1080" />
</state>
<state x="798" y="1516" key="NewPhpFileDialog/0.40.1680.1010/0.1050.1920.1080/1680.26.1280.1024@0.1050.1920.1080" timestamp="1604242319849" />
</component>
</project>
\ No newline at end of file
# Speedtest v3
## Installation
1. Clone
2. Copy `app/includes/config/config.sample.inc.php` to `app/includes/config/config.inc.php` and adjust values
3. Import `db.sql`
\ No newline at end of file
<?php
if (!isset($root)) {
$root = "../../";
}
function loadConfig()
{
global $root;
if (!file_exists($root . "app/includes/config/config.inc.php")) {
header("Location: /install");
die("config.inc.php does not exists. Please reinstall");
}
require_once $root . "app/includes/config/config.inc.php";
return $config;
}
$config = loadConfig();
if (!isset($config)) {
die("Malformed configuration!");
}
require_once $root . "app/includes/database.php";
$database = connectToMySQL($config['database_host'], $config['database_username'], $config['database_password'], $config['database_database']);
<?php
$config['database_host'] = "127.0.0.1";
$config['database_username'] = "user";
$config['database_password'] = "123";
$config['database_database'] = "password";
<?php
function connectToMySQL($host, $user, $password, $database)
{
try {
$db = new PDO("mysql:host=" . $host . ";charset=utf8mb4", $user, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->exec("USE `" . $database . "`;");
return $db;
} catch (PDOException $e) {
error_log("Critical Error: MySQL Connection error: " . $e->getMessage());
die('Sorry, but there was an error! Please contact the webmaster. Maybe maintenance?<br>If you are the webmaster, please check the log.');
}
}
<?php
$user_agent = $_SERVER['HTTP_USER_AGENT'];
function getOS()
{
global $user_agent;
$os_platform = "Unknown OS Platform";
$os_array = array(
'/windows nt 10/i' => 'Windows 10',
'/windows nt 6.3/i' => 'Windows 8.1',
'/windows nt 6.2/i' => 'Windows 8',
'/windows nt 6.1/i' => 'Windows 7',
'/windows nt 6.0/i' => 'Windows Vista',
'/windows nt 5.2/i' => 'Windows Server 2003/XP x64',
'/windows nt 5.1/i' => 'Windows XP',
'/windows xp/i' => 'Windows XP',
'/windows nt 5.0/i' => 'Windows 2000',
'/windows me/i' => 'Windows ME',
'/win98/i' => 'Windows 98',
'/win95/i' => 'Windows 95',
'/win16/i' => 'Windows 3.11',
'/macintosh|mac os x/i' => 'Mac OS X',
'/mac_powerpc/i' => 'Mac OS 9',
'/linux/i' => 'Linux',
'/ubuntu/i' => 'Ubuntu',
'/iphone/i' => 'iPhone',
'/ipod/i' => 'iPod',
'/ipad/i' => 'iPad',
'/android/i' => 'Android',
'/blackberry/i' => 'BlackBerry',
'/webos/i' => 'Mobile'
);
foreach ($os_array as $regex => $value)
if (preg_match($regex, $user_agent))
$os_platform = $value;
return $os_platform;
}
function getBrowser()
{
global $user_agent;
$browser = "Unknown Browser";
$browser_array = array(
'/msie/i' => 'Internet Explorer',
'/firefox/i' => 'Firefox',
'/safari/i' => 'Safari',
'/chrome/i' => 'Chrome',
'/edge/i' => 'Edge',
'/opera/i' => 'Opera',
'/netscape/i' => 'Netscape',
'/maxthon/i' => 'Maxthon',
'/konqueror/i' => 'Konqueror',
'/mobile/i' => 'Handheld Browser'
);
foreach ($browser_array as $regex => $value)
if (preg_match($regex, $user_agent))
$browser = $value;
return $browser;
}
function getLocationInfoByIp()
{
global $ip;
$ip_data = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $ip));
if ($ip_data && $ip_data->geoplugin_countryName != null) {
$result['country'] = $ip_data->geoplugin_countryCode;
$result['city'] = $ip_data->geoplugin_city;
}
return $result;
}
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;
}
\ No newline at end of file
-- phpMyAdmin SQL Dump
-- version 4.6.6deb5
-- https://www.phpmyadmin.net/
--
-- Host: localhost:3306
-- Erstellungszeit: 25. Jan 2019 um 21:49
-- Server-Version: 5.7.25-0ubuntu0.18.04.2
-- PHP-Version: 7.2.14-1+ubuntu18.04.1+deb.sury.org+1
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT = @@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS = @@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION = @@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Datenbank: `speedtest`
--
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `results`
--
CREATE TABLE `results`
(
`id` int(10) UNSIGNED NOT NULL,
`date` int(11) NOT NULL,
`dl` double NOT NULL,
`up` double DEFAULT NULL,
`ping` double DEFAULT NULL,
`ip` varchar(128) NOT NULL,
`isp` text NOT NULL,
`country` varchar(2) NOT NULL COMMENT 'Code 2 digs',
`km` int(11) NOT NULL
) ENGINE = InnoDB
DEFAULT CHARSET = latin1;
--
-- Indizes der exportierten Tabellen
--
--
-- Indizes für die Tabelle `results`
--
ALTER TABLE `results`
ADD UNIQUE KEY `id` (`id`);
--
-- AUTO_INCREMENT für exportierte Tabellen
--
--
-- AUTO_INCREMENT für Tabelle `results`
--
ALTER TABLE `results`
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
AUTO_INCREMENT = 53;
/*!40101 SET CHARACTER_SET_CLIENT = @OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS = @OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION = @OLD_COLLATION_CONNECTION */;
function I(id) {
return document.getElementById(id);
}
var meterBk = "#E0E0E0";
var dlColor = "#6060AA",
ulColor = "#309030",
pingColor = "#AA6060";
var progColor = "#EEEEEE";
//CODE FOR GAUGES
function drawMeter(c, amount, bk, fg, progress, prog) {
var ctx = c.getContext("2d");
var dp = window.devicePixelRatio || 1;
var cw = c.clientWidth * dp, ch = c.clientHeight * dp;
var sizScale = ch * 0.0055;
if (c.width == cw && c.height == ch) {
ctx.clearRect(0, 0, cw, ch);
} else {
c.width = cw;
c.height = ch;
}
ctx.beginPath();
ctx.strokeStyle = bk;
ctx.lineWidth = 16 * sizScale;
ctx.arc(c.width / 2, c.height - 58 * sizScale, c.height / 1.8 - ctx.lineWidth, -Math.PI * 1.1, Math.PI * 0.1);
ctx.stroke();
ctx.beginPath();
ctx.strokeStyle = fg;
ctx.lineWidth = 16 * sizScale;
ctx.arc(c.width / 2, c.height - 58 * sizScale, c.height / 1.8 - ctx.lineWidth, -Math.PI * 1.1, amount * Math.PI * 1.2 - Math.PI * 1.1);
ctx.stroke();
if (typeof progress !== "undefined") {
ctx.fillStyle = prog;
ctx.fillRect(c.width * 0.3, c.height - 16 * sizScale, c.width * 0.4 * progress, 4 * sizScale);
}
}
function mbpsToAmount(s) {
return 1 - (1 / (Math.pow(1.3, Math.sqrt(s))));
}
function msToAmount(s) {
return 1 - (1 / (Math.pow(1.08, Math.sqrt(s))));
}
//SPEEDTEST AND UI CODE
var w = null; //speedtest worker
var data = null; //data from worker
function startStop() {
if (w != null) {
//speedtest is running, abort
w.postMessage('abort');
w = null;
data = null;
I("startStopBtn").className = "";
initUI();
} else {
//test is not running, begin
w = new Worker('speedtest_worker.js');
w.postMessage('start ');
I("startStopBtn").className = "running";
I("shareArea").style.display = "none";
w.onmessage = function (e) {
data = JSON.parse(e.data);
var status = data.testState;
if (status >= 4) {
//test completed
I("startStopBtn").className = "";
w = null;
updateUI(true);
if (status == 4) {
//if testId is present, show sharing panel, otherwise do nothing
try {
var testId = Number(data.testId);
if (!isNaN(testId)) {
var shareURL = window.location.href.substring(0, window.location.href.lastIndexOf("/")) + "/get.app?id=" + testId;
I("resultsURL").value = shareURL;
I("testId").innerHTML = testId;
I("shareArea").style.display = "block";
}
} catch (e) {
}
}
}
};
}
}
//this function reads the data sent back by the worker and updates the UI
function updateUI(forced) {
if (!forced && (!data || !w)) return;
var status = data.testState;
I("dlText").textContent = (status == 1 && data.dlStatus == 0) ? "..." : data.dlStatus;
drawMeter(I("dlMeter"), mbpsToAmount(Number(data.dlStatus * (status == 1 ? oscillate() : 1))), meterBk, dlColor, Number(data.dlProgress), progColor);
I("ulText").textContent = (status == 3 && data.ulStatus == 0) ? "..." : data.ulStatus;
drawMeter(I("ulMeter"), mbpsToAmount(Number(data.ulStatus * (status == 3 ? oscillate() : 1))), meterBk, ulColor, Number(data.ulProgress), progColor);
I("pingText").textContent = data.pingStatus;
drawMeter(I("pingMeter"), msToAmount(Number(data.pingStatus * (status == 2 ? oscillate() : 1))), meterBk, pingColor, Number(data.pingProgress), progColor);
}
function oscillate() {
return 1 + 0.02 * Math.sin(Date.now() / 100);
}
//poll the status from the worker (this will call updateUI)
setInterval(function () {
if (w) w.postMessage('status');
}, 200);
//update the UI every frame
window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame || (function (callback, element) {
setTimeout(callback, 1000 / 60);
});
function frame() {
requestAnimationFrame(frame);
updateUI();
}
frame(); //start frame loop
//function to (re)initialize UI
function initUI() {
drawMeter(I("dlMeter"), 0, meterBk, dlColor, 0);
drawMeter(I("ulMeter"), 0, meterBk, ulColor, 0);
drawMeter(I("pingMeter"), 0, meterBk, pingColor, 0);
I("dlText").textContent = "";
I("ulText").textContent = "";
I("pingText").textContent = "";
}
<?php
header("HTTP/1.1 200 OK");
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Connection: keep-alive");
?>
\ No newline at end of file
<?php
// Disable Compression
@ini_set('zlib.output_compression', 'Off');
@ini_set('output_buffering', 'Off');
@ini_set('output_handler', '');
// Headers
header('HTTP/1.1 200 OK');
// Download follows...
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=random.dat');
header('Content-Transfer-Encoding: binary');
// Never cache me
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
// Generate data
$data = openssl_random_pseudo_bytes(1048576);
// Deliver chunks of 1048576 bytes
$chunks = isset($_GET['ckSize']) ? intval($_GET['ckSize']) : 4;
if (empty($chunks)) {
$chunks = 4;
}
if ($chunks > 100) {
$chunks = 100;
}
for ($i = 0; $i < $chunks; $i++) {
echo $data;
flush();
}
?>
<?php
$ip = "";
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['X-Real-IP'])) {
$ip = $_SERVER['X-Real-IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
$ip = preg_replace("/,.*/", "", $ip); # hosts are comma-separated, client is first
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
//if(filter_var($ip, FILTER_VALIDATE_IP)){
$ip = preg_replace("/^::ffff:/", "", $ip);
if (strpos($ip, '::1') !== false) {
echo '<p style="color: red">localhost!</p>';
die();
}
if (strpos($ip, '127.0.0') !== false) {
echo '<p style="color: red">localhost!</p>';
die();
}
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
echo '<p>Deine IPv4 Adresse: <b>' . $ip . '</b><br><span style="color:red">Achtung: Sie benutzten noch IPv4 und nicht IPv6. Bitte steigen sie auf IPv6 um, da es IPv4 nicht mehr lange geben wird!</span>';
} else if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
echo '<pDeine IPv6 Adresse: <b>' . $ip . '</b><br><span style="color:green">Gut: Sie benutzen schon IPv6 und nicht mehr IPv4!</span>';
}
$isp = "";
$rawIspInfo = null;
try {
$json = file_get_contents("https://ipinfo.io/" . $ip . "/json");
$details = json_decode($json, true);
$rawIspInfo = $details;
if (array_key_exists("org", $details))
$isp .= $details["org"];
else
$isp .= "Unknown ISP";
if (array_key_exists("country", $details))
$isp .= ", " . $details["country"];
$clientLoc = NULL;
$serverLoc = NULL;
if (array_key_exists("loc", $details))
$clientLoc = $details["loc"];
if ($clientLoc) {
$json = file_get_contents("https://ipinfo.io/json");
$details = json_decode($json, true);
if (array_key_exists("loc", $details))
$serverLoc = $details["loc"];
if ($serverLoc) {
try {
$clientLoc = explode(",", $clientLoc);
$serverLoc = explode(",", $serverLoc);
$dist = distance($clientLoc[0], $clientLoc[1], $serverLoc[0], $serverLoc[1]);
$dist = round($dist, -1);
if ($dist < 20)
$dist = "<20";
$isp .= ' <span class="ispkm">(' . $dist . ' km)</span>';
} catch (Exception $e) {
}
}
}
} catch (Exception $ex) {
$isp = "Unknown ISP";
}
echo '<p>Ihr <b>I</b>nternet <b>S</b>ervice <b>P</b>rovider: <b>' . $isp . '</b>';
//}
\ No newline at end of file
<?php
$root = "../";
require_once $root . "app/includes/autoload.php";
if(!isset($_GET['id'])){
header("Location: /");
die("Result not found");
}
$res = $database->prepare("SELECT * FROM `results` WHERE `id` = ?;");
$res->bindParam(1, $_GET['id']);
$res->execute();
if($res->rowCount() != 1){
header("Location: /");
die("Result not found");
}
$res = $res->fetch(PDO::FETCH_ASSOC);
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no" />
<title>Speedtest v3</title>
<link href="style.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="do.js"></script>
</head>
<body>
<h1>Speedtest</h1>
<div id="new-test" onclick="window.location = './';">Eigenen Speedtest machen</div>
<div class="accept-agb">Mit dem Verwenden des Speedtests stimmen sie den <a href="https://imprint.bixilon.de">Nutzerbedingungen & Datenschutzbestimmungen</a> zu!</div>
<div id="test">
<div class="testGroup">
<div class="testArea">
<div class="testName">Download</div>
<canvas id="dlMeter" class="meter"></canvas>
<div id="dlText" class="meterText"></div>
<div class="unit">Mbps</div>