Skip to content

Instantly share code, notes, and snippets.

@nanna-dk
Created September 30, 2021 10:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nanna-dk/3e64e6c6b6bab4186ded23d713f5ba8a to your computer and use it in GitHub Desktop.
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.
<?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