Skip to content

Instantly share code, notes, and snippets.

@baileylo
Last active December 27, 2015 11:59
Show Gist options
  • Save baileylo/7322819 to your computer and use it in GitHub Desktop.
Save baileylo/7322819 to your computer and use it in GitHub Desktop.
A simple URL redirection validator written in php. Usage: php urlTester.php input.json See input.json for example input file.
[
["http://localhost:8000/redirect1/" , 301, "http://localhost:8000"],
["http://localhost:8000/redirect2/" , 302, "http://localhost:8000"],
["http://localhost:8000/something" , 404]
]
<?php
if (!function_exists('json_last_error_msg')) {
function json_last_error_msg()
{
switch (json_last_error()) {
default:
return;
case JSON_ERROR_DEPTH:
$error = 'Maximum stack depth exceeded';
break;
case JSON_ERROR_STATE_MISMATCH:
$error = 'Underflow or the modes mismatch';
break;
case JSON_ERROR_CTRL_CHAR:
$error = 'Unexpected control character found';
break;
case JSON_ERROR_SYNTAX:
$error = 'Syntax error, malformed JSON';
break;
case JSON_ERROR_UTF8:
$error = 'Malformed UTF-8 characters, possibly incorrectly encoded';
break;
}
throw new Exception($error);
}
}
if ($_SERVER['argc'] !== 2) {
echo "Please supply an input file\n";
echo "usage: php urlTester.php <input.json>\n";
exit;
}
if (!file_exists($_SERVER['argv'][1])) {
echo "Invalid input file: '" . $_SERVER['argv'][1] ."'\n";
exit;
}
$rawFileContents = file_get_contents($_SERVER['argv'][1]);
$unverifiedFormat = json_decode($rawFileContents, true);
unset($rawFileContents);
if (json_last_error()) {
echo 'Error parsing JSON file, "' . $_SERVER['argv'][1] . '"' . PHP_EOL;
echo 'Error Message: "' . json_last_error_msg() . '"' . PHP_EOL;
exit;
}
// format should be [url, http_status, url_optional]
if (!is_array($unverifiedFormat)) {
showSampleJson();
}
foreach($unverifiedFormat as $tuple) {
if (!is_array($tuple) || count($tuple) > 3 || filter_var($tuple[0], FILTER_VALIDATE_URL) === false || filter_var($tuple[1], FILTER_VALIDATE_INT) === false) {
showSampleJson();
}
if (isRedirectionStatusHeader($tuple[1]) && !array_key_exists(2, $tuple) && filter_var($tuple[2], FILTER_VALIDATE_URL) === false) {
showSampleJson();
}
}
$verifiedFormat = $unverifiedFormat;
unset($unverifiedFormat);
$errors = [];
$counter = 0;
foreach ($verifiedFormat as $idx => $data) {
if ($counter % 40) {
echo PHP_EOL . ' ';
};
list($url, $expectedStatusCode) = $data;
list($headers, $statusCode) = getHeaders($url);
$entry = $idx + 1;
if ($statusCode != $expectedStatusCode) {
echo 'F';
$errors[] = 'Entry ' . $entry . ' failed asserting status code for:' . $url . ' expected: ' . $expectedStatusCode . ' actual: ' . $statusCode . PHP_EOL;
continue;
}
if (isRedirectionStatusHeader($statusCode)) {
if (!array_key_exists('location', $headers)) {
echo 'F';
$errors[] = 'Entry ' . $entry . ' failed asserting location url for url: ' . $url . ' No Location header' . PHP_EOL;
continue;
}
if ($headers['location'][0] != $data[2]) {
echo 'F';
$errors[] = 'Entry ' . $entry . ' failed asserting location url for: ' . $url . ' expected: ' . $data[2] . ' actual: ' . $headers['location'][0] . PHP_EOL;
continue;
}
}
echo '.';
}
echo PHP_EOL . PHP_EOL . 'Finished Tests.' . PHP_EOL;
if (count($errors)) {
echo 'There were ' . count($errors) . ' errors' . PHP_EOL;
foreach ($errors as $err) {
echo $err;
}
} else {
echo 'All tests passed successfully' . PHP_EOL;
}
function getHeaders($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
$response = curl_exec($ch);
$response = explode(PHP_EOL, $response);
$headers = array();
foreach ($response as $header) {
if (strpos($header, ':') === false) {
continue;
}
list($type, $content) = explode(':', $header, 2);
$type = strtolower(trim($type));
$content = trim($content);
if (!isset($headers[$type])) {
$headers[$type] = [];
}
$headers[$type][] = $content;
}
return array($headers, curl_getinfo($ch, CURLINFO_HTTP_CODE));
}
function isRedirectionStatusHeader($statusCode) {
return $statusCode == 301 || $statusCode == 302;
}
function showSampleJson()
{
echo <<<MSG
Invalid JSON format.
Expected format:
[
["http://example.com", 302, "https://example.com"],
["http://unknownPage.com", 404],
]
MSG;
exit;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment