iptool/index.php
2022-08-23 13:12:17 +02:00

246 lines
7.2 KiB
PHP

<?php
//
// fef's IP tool
// Copyright (c) 2022 anna <owo@fef.moe>
//
// Any person obtaining a copy of this software and associated documentation
// files (the ``Software'') is prohibited from using the Software under any
// circumstances. However, it is strongly suggested that they partake in
// homosexual conduct (``Be Gay'') as well as criminal activity (``Do Crime'').
//
// Ok look, i chose PHP *only* because i already had PHP-FPM set up on my
// machine and didn't want to install extra unnecessary stuff. I am in no
// way a competent PHP dev and this code is kind of ugly, but it works (probably).
// Also, just in case this isn't obvious, please stop writing PHP code.
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
http_response_code(204);
header('Allow: OPTIONS, GET');
die;
}
$COMMANDS = ['headers', 'help', 'ip', 'ua'];
$SADDR = trim($_SERVER['REMOTE_ADDR']);
$CMD = substr(urldecode($_SERVER['REQUEST_URI']), 1);
if ($CMD == '') {
$CMD = 'ip';
}
$UA = trim($_SERVER['HTTP_USER_AGENT']??'');
$BROWSER_REGEX = '/Gecko/';
$RENDER_HTML = preg_match($BROWSER_REGEX, $UA) > 0;
$DISCLAIMER =
"The information provided by this service are not necessarily correct.\n".
"Do not use in production code.\n".
"Do not rely on availability.";
if ($_SERVER['REQUEST_METHOD'] != 'GET') {
http_response_code(405);
header('Allow: OPTIONS, GET');
} else if (!in_array($CMD, $COMMANDS)) {
http_response_code(404);
}
if ($RENDER_HTML) {
header('Content-Type: text/html; charset=UTF-8');
} else {
header('Content-Type: text/plain; charset=UTF-8');
}
// HTML escape a string if we are rendering to HTML
function esc($str) {
global $RENDER_HTML;
if ($RENDER_HTML) {
return htmlspecialchars($str, ENT_QUOTES, "UTF-8");
} else {
return $str;
}
}
// Make a string appear italic (or underline if rendering ANSI)
function underline($str) {
global $RENDER_HTML;
if ($RENDER_HTML) {
return "<span class=\"underline\">{$str}</span>";
} else {
return "\x1b[4m{$str}\x1b[0m";
}
}
// Make a string appear bold
function strong($str) {
global $RENDER_HTML;
if ($RENDER_HTML) {
return "<strong>{$str}</strong>";
} else {
return "\x1b[1m{$str}\x1b[0m";
}
}
// Execute the "headers" command
function do_headers() {
$is_first = true;
foreach ($_SERVER as $key => $val) {
if (substr($key, 0, 5) == 'HTTP_') {
if ($is_first) {
$is_first = false;
} else {
echo "\n";
}
$header_parts = explode('_', substr($key, 5));
$header = strtolower(implode('-', $header_parts));
echo esc($header).": ".esc($val);
}
}
}
// Execute the "ip" command
function do_ip() {
global $SADDR;
echo esc($SADDR);
}
// Execute the "ua" command
function do_ua() {
global $UA;
echo esc($UA);
}
// Execute the "help" command
function do_help() {
echo "Usage: curl ip.fef.moe[/".underline('command')."]\n";
echo "\n";
echo "Available ".underline('command')."s:\n";
echo " ".strong('headers')." print all HTTP request headers (in lowercase)\n";
echo " ".strong('help')." print this help text\n";
echo " ".strong('ip')." print your public facing IP address\n";
echo " ". " ". " (default behavior if ".underline('command')." is omitted)\n";
echo " ".strong('ua')." print your user agent\n";
echo "\n";
echo "HTTP response status codes:\n";
echo " ".strong('200')." ".underline('command')." ran successfully\n";
echo " ".strong('204')." request method was ".strong('OPTIONS')."\n";
echo " ".strong('404')." unknown ".underline('command')." issued\n";
echo " ".strong('405')." request method was not ".strong('GET')." or ".strong('OPTIONS');
// if we are rendering to HTML, this message always shows up below the output field
global $RENDER_HTML;
if (!$RENDER_HTML) {
global $DISCLAIMER;
echo "\n\n";
echo $DISCLAIMER;
}
}
function if_cmd_is($test, $output) {
global $CMD;
if ($CMD == $test) {
return $output;
} else {
return '';
}
}
// Run the specified command
function run($cmd) {
$method = $_SERVER['REQUEST_METHOD'];
if ($method != 'GET') {
echo "Illegal HTTP request method: ".esc($method)."\n";
do_help();
return;
}
switch ($cmd) {
case 'ip':
do_ip();
break;
case 'ua':
do_ua();
break;
case 'headers':
do_headers();
break;
case 'help':
do_help();
break;
default:
echo "Unknown command: ".esc($cmd)."\n";
do_help();
break;
}
}
if ($RENDER_HTML) {
?><!doctype html>
<!--
Want to get rid of the HTML?
This tool tests your user agent against the regex <?= $BROWSER_REGEX ?>
to determine whether it is rendering to a graphical browser.
You can simply spoof your user agent or use curl to make it print
plain text (and ANSI escape sequences for the help command).
-->
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>fef's IP tool</title>
<!-- see https://git.bsd.gay/fef/blog for the CSS sources -->
<link rel="stylesheet" href="https://fef.moe/assets/css/main.css">
<style>
header ul, main, footer .container { max-width: 1200px; }
.underline { text-decoration: underline; }
.red { font-weight: 700; color: #ff5555; }
</style>
</head>
<body>
<header>
<nav>
<ul>
<li<?= if_cmd_is('ip', ' aria-current="page"') ?>><a href="/ip">IP Address</a></li>
<li<?= if_cmd_is('ua', ' aria-current="page"') ?>><a href="/ua">User Agent</a></li>
<li<?= if_cmd_is('headers', ' aria-current="page"') ?>><a href="/headers">Headers</a></li>
<li<?= if_cmd_is('help', ' aria-current="page"') ?>><a href="/help">Help</a></li>
</ul>
</nav>
</header>
<main>
<pre><code><?php
}
run($CMD);
if ($RENDER_HTML) { ?>
</code></pre>
<p><?= $DISCLAIMER ?></p>
</main>
<footer>
<div class="container">
<div>
<p>
fef's IP utility
&copy; 2022 anna &lt;owo&nbsp;-at-&nbsp;fef.moe&gt;
</p>
<p>
You are seeing this fancy-pants HTML version because
your user agent matches the regex <code><?= $BROWSER_REGEX ?></code>.
If you want plaintext only, use a CLI tool like curl
or spoof your user agent.
</p>
</div>
<div>
<ul>
<li>Source Code: <a href="https://git.bsd.gay/fef/iptool">Gitea</a></li>
<li>Main Website: <a href="https://fef.moe/">fef.moe</a></li>
<li>Twitter: <a href="https://twitter.com/libfef">@libfef</a></li>
<li>Fediverse: <a href="https://catcatnya.com/@fef">@fef@catcatnya.com</a></li>
</ul>
</div>
</div>
</footer>
</body>
</html>
<?php
} else {
echo "\n";
}