Created
September 30, 2021 10:20
-
-
Save nanna-dk/3e64e6c6b6bab4186ded23d713f5ba8a to your computer and use it in GitHub Desktop.
PHP proxy for xml/rss feeds - sets headers (domains and subdomains) to fix CORS issues. Works with POST and GET.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
* PHP Proxy: Outputs content with appropiate headers to fix CORS issues. | |
* Responds to both HTTP GET and POST requests | |
* Usage in javascript: thisFile.php?url=" + encodeURIComponent(feedUrl) + "&mimeType=application/rss+xml"; | |
*/ | |
// Get the url of to be proxied | |
// Is it a POST or a GET? | |
if (isset($_POST['url']) || isset($_GET['url'])) { | |
$url = ($_POST['url']) ? $_POST['url'] : $_GET['url']; | |
$url = filter_var($url, FILTER_SANITIZE_URL); | |
$url = filter_var($url, FILTER_VALIDATE_URL); | |
$scheme = parse_url($url, PHP_URL_SCHEME); | |
// Check for host - file://, ftp:// etc. are not allowed. | |
if (! in_array($scheme, ['http', 'https'])) { | |
return; | |
} | |
$headers = ($_POST['headers']) ? $_POST['headers'] : $_GET['headers']; | |
function getCORSHeaderOrigin($allowed, $input) { | |
// Function to allow headers from subdomains | |
if ('*' == $allowed) { | |
return '*'; | |
} | |
if (! is_array($allowed)) { | |
$allowed = [$allowed]; | |
} | |
foreach ($allowed as &$value) { | |
$value = preg_quote($value, '/'); | |
if (false !== ($wildcardPos = strpos($value, '\*'))) { | |
$value = str_replace('\*', '(.*)', $value); | |
} | |
} | |
$regexp = '/^('.implode('|', $allowed).')$/'; | |
$inputHost = parse_url($input, PHP_URL_HOST); | |
if (null === $inputHost || ! preg_match($regexp, $inputHost, $matches)) { | |
return 'none'; | |
} | |
return $input; | |
} | |
$mimeType = ($_POST['mimeType']) ? $_POST['mimeType'] : $_GET['mimeType']; | |
//Start the Curl session | |
$session = curl_init($url); | |
// If it's a POST, put the POST data in the body | |
if ($_POST['url']) { | |
$postvars = ''; | |
while ($element = current($_POST)) { | |
$postvars .= key($_POST).'='.$element.'&'; | |
next($_POST); | |
} | |
curl_setopt($session, CURLOPT_POST, true); | |
curl_setopt($session, CURLOPT_POSTFIELDS, $postvars); | |
} | |
// Don't return HTTP headers. Do return the contents of the call | |
curl_setopt($session, CURLOPT_HEADER, ('true' == $headers) ? true : false); | |
curl_setopt($session, CURLOPT_FOLLOWLOCATION, true); | |
//curl_setopt($session, CURLOPT_TIMEOUT, 4); | |
curl_setopt($session, CURLOPT_RETURNTRANSFER, true); | |
// Make the call | |
$response = curl_exec($session); | |
if ('' != $mimeType) { | |
// The web service returns XML. Set the Content-Type appropriately | |
header('Content-Type: '.$mimeType); | |
header('Access-Control-Allow-Methods: GET, POST, OPTIONS'); | |
if (isset($_SERVER['HTTP_ORIGIN'])) { | |
header('Access-Control-Allow-Origin: '.getCORSHeaderOrigin(['*.domain.com', 'localhost', 'https//www.specific-site.com'], $_SERVER['HTTP_ORIGIN'])); | |
} | |
} | |
echo $response; | |
curl_close($session); | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment