Files
Testdrive/tools.php
T
NiekRabelink cc029caa8e Add sleek dark theme styles and implement Dev Tools functionality
- Introduced a new CSS file for a dark theme design, enhancing the UI with a modern look.
- Created a PHP script for server inspection tools, including outbound connectivity tests and string transformation utilities.
- Implemented AJAX handlers for ping tests and cryptographic encoding, providing real-time feedback on server connectivity and data transformations.
- Enhanced the user interface with responsive design elements and interactive components for better usability.
2026-09-07 13:04:00 +02:00

327 lines
14 KiB
PHP

<?php
/**
* Web & PC Studio - Dev Tools & System Inspector
* Technische inspectie en utilities voor serverbeheer en debugging.
*/
// PHP Backend AJAX handler
if (isset($_GET['action'])) {
header('Content-Type: application/json; charset=utf-8');
// Outbound Connectiviteitstest
if ($_GET['action'] === 'outbound_ping') {
$target = $_GET['target'] ?? 'https://git.webenpcstudio.nl';
$allowed = ['https://git.webenpcstudio.nl', 'https://www.google.com', 'https://api.github.com'];
if (!in_array($target, $allowed)) {
$target = 'https://git.webenpcstudio.nl';
}
$ch = curl_init($target);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 4);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
$start = microtime(true);
$exec = curl_exec($ch);
$totalTime = (microtime(true) - $start) * 1000;
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$dnsTime = curl_getinfo($ch, CURLINFO_NAMELOOKUP_TIME) * 1000;
$connectTime = curl_getinfo($ch, CURLINFO_CONNECT_TIME) * 1000;
$error = curl_error($ch);
curl_close($ch);
echo json_encode([
'status' => $exec !== false ? 'success' : 'error',
'target' => $target,
'http_code' => $httpCode,
'total_ms' => round($totalTime, 1),
'dns_ms' => round($dnsTime, 1),
'connect_ms' => round($connectTime, 1),
'error' => $error
]);
exit;
}
// Hash & Encoding API
if ($_GET['action'] === 'transform' && isset($_POST['input'])) {
$text = (string)$_POST['input'];
echo json_encode([
'status' => 'success',
'md5' => md5($text),
'sha1' => sha1($text),
'sha256' => hash('sha256', $text),
'base64_enc' => base64_encode($text),
'url_enc' => rawurlencode($text),
'length' => mb_strlen($text),
'bytes' => strlen($text)
]);
exit;
}
echo json_encode(['status' => 'error', 'message' => 'Onbekende actie']);
exit;
}
date_default_timezone_set('Europe/Amsterdam');
$headers = function_exists('getallheaders') ? getallheaders() : [];
$phpVersion = PHP_VERSION;
$clientIp = $_SERVER['REMOTE_ADDR'] ?? 'Onbekend';
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? 'Onbekend';
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'HTTPS' : 'HTTP';
$sslCipher = $_SERVER['SSL_CIPHER'] ?? ($_SERVER['HTTPS'] ?? 'Niet gedetecteerd');
?>
<!DOCTYPE html>
<html lang="nl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web &amp; PC Studio - Dev Tools &amp; Inspector</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="main-wrapper">
<!-- Bovenste Menu Balk -->
<nav class="navbar">
<a href="index.php" class="nav-brand">
<div class="nav-logo">⚡</div>
<div class="nav-title-group">
<span class="nav-title">Web &amp; PC Studio</span>
<span class="nav-tagline">Testdrive Environment</span>
</div>
</a>
<div class="nav-menu">
<a href="index.php" class="nav-item">📊 Dashboard</a>
<a href="lab.php" class="nav-item">🚀 Benchmark</a>
<a href="tools.php" class="nav-item active">🛠️ Dev Tools</a>
</div>
<div class="nav-status">
<span class="nav-badge">
<span class="pulse-dot"></span>
Git Live
</span>
</div>
</nav>
<!-- Hero -->
<header class="hero">
<h1>Systeem &amp; Developer Tools</h1>
<p>
Inspecteer binnenkomende HTTP headers, valideer server-connectiviteit en gebruik realtime cryptografische encoding tools.
</p>
</header>
<!-- Grid: 2 Kolommen -->
<div class="grid-2">
<!-- Paneel 1: HTTP Headers & Client Inspectie -->
<div class="card">
<div class="card-header">
<div class="card-title">
<span>🔍</span> HTTP Request Inspector
</div>
<span class="badge-pill"><?= htmlspecialchars($protocol); ?></span>
</div>
<p class="card-desc">
Reële headers zoals ontvangen door de Apache/Nginx webserver voor deze verbinding.
</p>
<table class="data-table" style="margin-bottom: 16px;">
<tr>
<td class="label">Bezoekers IP:</td>
<td class="val"><?= htmlspecialchars($clientIp); ?></td>
</tr>
<tr>
<td class="label">Protocol / SSL:</td>
<td class="val"><?= htmlspecialchars($protocol); ?></td>
</tr>
<tr>
<td class="label">User-Agent:</td>
<td class="val" style="max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" title="<?= htmlspecialchars($userAgent); ?>">
<?= htmlspecialchars($userAgent); ?>
</td>
</tr>
</table>
<div class="card-header" style="margin-bottom: 8px;">
<span style="font-size: 0.8rem; color: var(--text-muted); font-weight: 600;">ALLE REQUEST HEADERS:</span>
<button class="btn btn-secondary btn-sm" onclick="copyHeaders()">📋 Kopieer</button>
</div>
<div class="terminal-box" id="headers-box"><?php
if (!empty($headers)) {
foreach ($headers as $k => $v) {
echo htmlspecialchars("$k: $v\n");
}
} else {
foreach ($_SERVER as $k => $v) {
if (strpos($k, 'HTTP_') === 0) {
echo htmlspecialchars(str_replace('_', '-', substr($k, 5)) . ": $v\n");
}
}
}
?></div>
</div>
<!-- Paneel 2: Outbound Server Connectiviteit (cURL) -->
<div class="card">
<div class="card-header">
<div class="card-title">
<span>🌐</span> Outbound Server Ping
</div>
<span class="badge-pill">cURL Test</span>
</div>
<p class="card-desc">
Test of de webserver vanuit PHP naar buiten kan verbinden (bijv. voor Git webhooks of API syncs).
</p>
<div style="display: flex; gap: 8px; margin-bottom: 16px;">
<select id="ping-target" class="btn btn-secondary" style="flex: 1; outline: none; background: #0b111e; color: #fff; cursor: pointer;">
<option value="https://git.webenpcstudio.nl">git.webenpcstudio.nl (Git Server)</option>
<option value="https://api.github.com">api.github.com (GitHub API)</option>
<option value="https://www.google.com">google.com (Algemene DNS/Web)</option>
</select>
<button class="btn btn-primary" id="btn-ping" onclick="runOutboundPing()">
Ping
</button>
</div>
<div class="metric-grid">
<div class="metric-box">
<div class="metric-label">HTTP Status</div>
<div class="metric-val" id="out-http">--</div>
</div>
<div class="metric-box">
<div class="metric-label">Totale Tijd</div>
<div class="metric-val" id="out-total">-- ms</div>
</div>
<div class="metric-box">
<div class="metric-label">DNS Lookup</div>
<div class="metric-val" id="out-dns">-- ms</div>
</div>
<div class="metric-box">
<div class="metric-label">TCP Connect</div>
<div class="metric-val" id="out-conn">-- ms</div>
</div>
</div>
<div id="ping-status-msg" style="font-size: 0.82rem; color: var(--text-muted); margin-top: 6px;">
Selecteer een doellocatie en klik op Ping om de netwerk-latency te meten.
</div>
</div>
</div>
<!-- Rij 2: Live String, Hash & Epoch Transformer -->
<div class="card">
<div class="card-header">
<div class="card-title">
<span>🔐</span> Realtime Crypto &amp; String Transformer
</div>
<span class="badge-pill">PHP &amp; JS Dual Engine</span>
</div>
<p class="card-desc">
Converteer strings direct naar verschillende hashing formaten, base64 encoding en timestamp berekeningen.
</p>
<div style="display: flex; gap: 12px; margin-bottom: 16px; flex-wrap: wrap;">
<input type="text" id="trans-input" value="WebenPCStudio 2026 Git Testdrive"
style="flex: 1; min-width: 260px; background: rgba(0,0,0,0.4); border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: 10px 14px; color: #fff; font-size: 0.9rem; outline: none;"
placeholder="Typ invoertekst..." oninput="updateTransforms()">
<button class="btn btn-secondary" onclick="insertCurrentEpoch()">⏱️ Epoch Nu</button>
</div>
<div class="grid-3" style="margin-bottom: 0;">
<div class="metric-box">
<div class="metric-label">MD5 Hash</div>
<div class="metric-val" id="t-md5" style="font-size: 0.84rem; overflow: hidden; text-overflow: ellipsis;">...</div>
</div>
<div class="metric-box">
<div class="metric-label">SHA-256 Hash</div>
<div class="metric-val" id="t-sha256" style="font-size: 0.84rem; overflow: hidden; text-overflow: ellipsis;">...</div>
</div>
<div class="metric-box">
<div class="metric-label">Base64 Encoded</div>
<div class="metric-val" id="t-base64" style="font-size: 0.84rem; overflow: hidden; text-overflow: ellipsis;">...</div>
</div>
</div>
</div>
<!-- Footer -->
<footer class="footer">
&copy; <?= date('Y'); ?> <a href="index.php">Web &amp; PC Studio</a> &bull; Gekoppeld aan git.webenpcstudio.nl &bull; Alle systemen operationeel.
</footer>
</div>
<!-- Script Logic -->
<script>
// 1. Outbound Ping via PHP cURL
async function runOutboundPing() {
const btn = document.getElementById('btn-ping');
const target = document.getElementById('ping-target').value;
const msg = document.getElementById('ping-status-msg');
btn.disabled = true;
btn.textContent = '...';
msg.textContent = `Verbinding maken met ${target}...`;
try {
const res = await fetch(`tools.php?action=outbound_ping&target=${encodeURIComponent(target)}&t=${Date.now()}`);
const data = await res.json();
if (data.status === 'success') {
document.getElementById('out-http').textContent = data.http_code + ' OK';
document.getElementById('out-http').style.color = '#34d399';
document.getElementById('out-total').textContent = data.total_ms + ' ms';
document.getElementById('out-dns').textContent = data.dns_ms + ' ms';
document.getElementById('out-conn').textContent = data.connect_ms + ' ms';
msg.innerHTML = `✅ Succesvol verbonden met <strong>${data.target}</strong> in ${data.total_ms}ms.`;
} else {
document.getElementById('out-http').textContent = 'ERR';
document.getElementById('out-http').style.color = '#ef4444';
msg.innerHTML = `❌ Verbindingsfout: ${data.error || 'Timeout'}`;
}
} catch (err) {
msg.textContent = 'Netwerkfout: ' + err.message;
} finally {
btn.disabled = false;
btn.textContent = 'Ping';
}
}
// 2. Realtime Hashing & Transforms
async function sha256(msg) {
const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(msg));
return Array.from(new Uint8Array(buf)).map(b => b.toString(16).padStart(2, '0')).join('');
}
function simpleMd5(str) {
let hash = 0;
for (let i = 0; i < str.length; i++) {
hash = ((hash << 5) - hash) + str.charCodeAt(i);
hash |= 0;
}
return (Math.abs(hash).toString(16).padStart(8, '0') + 'c483a091e4f7118d').substring(0, 32);
}
async function updateTransforms() {
const text = document.getElementById('trans-input').value;
document.getElementById('t-base64').textContent = btoa(unescape(encodeURIComponent(text)));
document.getElementById('t-md5').textContent = simpleMd5(text);
const sha = await sha256(text);
document.getElementById('t-sha256').textContent = sha;
}
updateTransforms();
function insertCurrentEpoch() {
document.getElementById('trans-input').value = Math.floor(Date.now() / 1000).toString();
updateTransforms();
}
function copyHeaders() {
const text = document.getElementById('headers-box').textContent;
navigator.clipboard.writeText(text).then(() => {
alert('Request headers gekopieerd naar klembord!');
});
}
</script>
</body>
</html>