diff --git a/index.php b/index.php new file mode 100644 index 0000000..3698e82 --- /dev/null +++ b/index.php @@ -0,0 +1,248 @@ += 0; $index--) { + // find and validate the position of the character in the charset + $char = $string[$index]; + $pos = array_search($char, $chars); + if ($pos === false) { + return "Character not in set: $char"; + } + // if the character is not the last in the charset, increment it and break + if ($pos < count($chars) - 1) { + $string[$index] = $chars[$pos + 1]; + break; + } + // character is the last in the charset; wrap around to the first character + $string[$index] = $chars[0]; + // if we are at the beginning of the string, prepend the first character and break + if ($index === 0) { + array_unshift($string, $chars[0]); + break; + } + } + return join('', $string); +} + +// Splits a string into an array of characters +function str_to_chars($str, $l = 0) { + if ($l > 0) { + $ret = array(); + $len = mb_strlen($str, "UTF-8"); + for ($i = 0; $i < $len; $i += $l) { + $ret[] = mb_substr($str, $i, $l, "UTF-8"); + } + return $ret; + } + return preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY); +} + +// Reads the last key, increments it, saves it, and returns it +function next_key() { + $last = get_last(); + $next = increment_string($last); + set_last($next); + return $next; +} + +// Adds a URL to urls.txt and returns the generated key +function add_url($url) { + global $urls_file; + $key = next_key(); + // append the key and url to urls.txt + file_put_contents($urls_file, $key . ' ' . $url . "\n", FILE_APPEND); + return $key; +} + +// Looks up a key in urls.txt and returns the corresponding URL, or null if not found +function get_url($key) { + global $urls_file; + $lines = file($urls_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + foreach ($lines as $line) { + list($k, $url) = explode(' ', $line, 2); + if ($k === $key) { + return $url; + } + } + return null; +} + +// Test function to print a series of incremented keys +// Usage: output_keys('', 100); +function output_keys($key, $count) { + header('Content-Type: text/plain'); + for ($i = 0; $i < $count; $i++) { + $key = increment_string($key); + // set content type to plain text + print($key . "\n"); + } +} + +// Get input either from a GET or POST request +function get_input($name) { + if (isset($_POST[$name])) { + return $_POST[$name]; + } elseif (isset($_GET[$name])) { + return $_GET[$name]; + } + return null; +} + +// Test if a host is in the allowed domains list +function test_host($host) { + global $allowed_domains; + if (empty($allowed_domains)) { + return true; // if the list is empty, allow all domains + } + return in_array($host, $allowed_domains); +} + + +/* HTTP Request Handling */ + +// read input parameters +$url = get_input('url'); +$input_password = get_input('password'); +$key = get_input('key'); +$test_start = get_input('test_start'); +$test_count = get_input('test_count'); + +// If a URL is provided, attempt to shorten it +if ($url) { + // if a password is set, check it + if ($password !== '' && $input_password !== $password) { + http_response_code(401); // Unauthorized + echo "Unauthorized: Incorrect password.\n"; + exit; + } + // return 422 if the URL is longer than max_url_length + if (strlen($url) > $max_url_length) { + http_response_code(422); // Unprocessable Entity + echo "Invalid URL.\n"; + exit; + } + // return 403 if the URL's domain is not in the allowed list + $parsed_url = parse_url($url); + if ($parsed_url === false || !isset($parsed_url['host']) || !test_host($parsed_url['host'])) { + http_response_code(403); + echo "Forbidden: This URL is not within the list of allowed domains.\n"; + exit; + } + // validate the URL and shorten it + if (filter_var($url, FILTER_VALIDATE_URL)) { + $key = add_url($url); + $shortened_url = "https://$_SERVER[HTTP_HOST]/$key"; + echo "$shortened_url\n"; + } else { + http_response_code(422); // Unprocessable Entity + echo "Invalid URL.\n"; + } + exit; +} + +// If test parameters are provided, output a series of incremented keys +if ($enabed_test && $test_start !== null && $test_count !== null) { + // validate password + if ($password !== '' && $input_password !== $password) { + http_response_code(401); // Unauthorized + echo "Unauthorized: Incorrect password.\n"; + exit; + } + output_keys($test_start, (int)$test_count); + exit; +} + +// Otherwise, assume the request URI is a key to look up +$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); +$key = trim($path, '/'); + +// If the key is valid, look up the URL and redirect +if ($key !== '') { + $url = get_url($key); + if ($url !== null) { + header("Location: $url", true, 301); + exit; + } else { + http_response_code(404); + echo "Not Found.\n"; + exit; + } +} +// If no key or url is provided, show a simple HTML form to submit a URL +?> + + +
+ + +