182 lines
5.3 KiB
PHP
182 lines
5.3 KiB
PHP
|
<?php
|
||
|
class RedirectCheck
|
||
|
{
|
||
|
// constants
|
||
|
const USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36";
|
||
|
const ERROR_CURL_INIT = "Couldn't initialize a cURL handle";
|
||
|
const ERROR_CURL_CODE = "Could not curl_getinfo the HTTP code";
|
||
|
const ERROR_CURL_REDIRECT = "Could not curl_getinfo the redirect URL";
|
||
|
|
||
|
// properties
|
||
|
public string $url;
|
||
|
public string $next;
|
||
|
public int $code;
|
||
|
public int $step;
|
||
|
public bool $redirect;
|
||
|
public array $path;
|
||
|
public array $error;
|
||
|
|
||
|
// constructor
|
||
|
public function __construct(string $url)
|
||
|
{
|
||
|
$this->url = $url;
|
||
|
$this->next = '';
|
||
|
$this->code = 0;
|
||
|
$this->step = 1;
|
||
|
$this->redirect = false;
|
||
|
$this->error = [];
|
||
|
$this->path[$this->step] = [
|
||
|
'step' => $this->step,
|
||
|
'url' => $this->url,
|
||
|
'code' => null,
|
||
|
'next' => null ];
|
||
|
}
|
||
|
|
||
|
// create an error message
|
||
|
private function setError(array $error): void
|
||
|
{
|
||
|
$this->error = $error;
|
||
|
}
|
||
|
|
||
|
// add an entry to the URL path
|
||
|
private function addPath(int $step, array $path): void
|
||
|
{
|
||
|
$this->path[$step] = $path;
|
||
|
}
|
||
|
|
||
|
// update a path entry
|
||
|
public function updatePath(int $step, string $key, string $value): void
|
||
|
{
|
||
|
$this->path[$step][$key] = $value;
|
||
|
}
|
||
|
|
||
|
// create a curl request for a URL
|
||
|
public function getHttpCode()
|
||
|
{
|
||
|
// initate curl request
|
||
|
$ch = curl_init();
|
||
|
if (!$ch) {
|
||
|
$this->setError = ['type' => 'curl', 'message' => self::ERROR_CURL_INIT];
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// set request headers and execute
|
||
|
$response = curl_setopt($ch, CURLOPT_URL, $this->url);
|
||
|
$response = curl_setopt($ch, CURLOPT_HEADER, true); // enable this for debugging
|
||
|
$response = curl_setopt($ch, CURLOPT_HTTPGET, true); // redundant but making sure it's a GET
|
||
|
$response = curl_setopt($ch, CURLOPT_NOBODY, false); // settings this to true was returning 405s
|
||
|
$response = curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
|
||
|
$response = curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // return output instead of going to screen
|
||
|
$response = curl_setopt($ch, CURLOPT_TIMEOUT, 60);
|
||
|
$response = curl_setopt($ch, CURLOPT_USERAGENT, self::USER_AGENT);
|
||
|
$response = curl_exec($ch);
|
||
|
|
||
|
// check for a response
|
||
|
if (empty($response))
|
||
|
{
|
||
|
$this->setError(['type' => 'curl', 'message' => curl_error($ch)]);
|
||
|
curl_close($ch);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// get the http status code
|
||
|
if (curl_getinfo($ch, CURLINFO_HTTP_CODE))
|
||
|
{
|
||
|
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||
|
$this->code = ($code) ? $code : 0;
|
||
|
if ($code == 200) {
|
||
|
$this->updatePath($this->step, 'code', $this->code);
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$this->code = 0;
|
||
|
$this->setError(['type' => 'curl', 'message' => self::ERROR_CURL_CODE]);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// get any redirect url to follow next
|
||
|
if (curl_getinfo($ch, CURLINFO_REDIRECT_URL))
|
||
|
{
|
||
|
$next = curl_getinfo($ch, CURLINFO_REDIRECT_URL);
|
||
|
$this->redirect = ($next) ? true : false;
|
||
|
$this->next = ($next) ? $next : '';
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
$this->redirect = false;
|
||
|
$this->next = '';
|
||
|
}
|
||
|
|
||
|
// close the session
|
||
|
curl_close($ch);
|
||
|
|
||
|
// update the current path
|
||
|
$this->updatePath($this->step, 'code', $this->code);
|
||
|
$this->updatePath($this->step, 'next', $this->next);
|
||
|
|
||
|
// start the next path
|
||
|
$this->step++;
|
||
|
$this->addPath(
|
||
|
$this->step,
|
||
|
[
|
||
|
'step' => $this->step,
|
||
|
'url' => $this->next,
|
||
|
'code' => null,
|
||
|
'next' => null
|
||
|
]);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
// return false if we get here
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// get the final URL redirect
|
||
|
public function getFinalRedirect(): string
|
||
|
{
|
||
|
$last = end($this->path);
|
||
|
return $last['url'];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// handle form submissions
|
||
|
if (isset($_POST['url']))
|
||
|
{
|
||
|
// check that we got a valid URL
|
||
|
$url = (filter_var(trim($_POST['url']), FILTER_VALIDATE_URL))
|
||
|
? trim($_POST['url'])
|
||
|
: false;
|
||
|
|
||
|
// if so, start up the redirect checks
|
||
|
if ($url)
|
||
|
{
|
||
|
// make a request for this url and add to the path
|
||
|
$request = new RedirectCheck($url);
|
||
|
$code = '';
|
||
|
|
||
|
do {
|
||
|
// set the URL
|
||
|
$request->url = $url;
|
||
|
|
||
|
// make the curl request and update the path
|
||
|
$request->getHttpCode();
|
||
|
|
||
|
// end on an error
|
||
|
if ($request->error)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// if we have a redirect to follow, update our working $url
|
||
|
$url = ($request->next) ? $request->next : false;
|
||
|
|
||
|
// update our code
|
||
|
$code = ($request->code) ? $request->code : false;
|
||
|
|
||
|
} while ($code != 200);
|
||
|
}
|
||
|
}
|
||
|
?>
|