Created
April 9, 2020 06:44
-
-
Save Elavarasanlee/4cee04c7cdafa869e6e55383fab1813b to your computer and use it in GitHub Desktop.
proxy.php is gist modified for personal use from https://github.com/softius/php-cross-domain-proxy
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 | |
/** | |
* AJAX Cross Domain (PHP) Proxy 0.8 | |
* Copyright (C) 2016 Iacovos Constantinou (https://github.com/softius) | |
* | |
* This program is free software: you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License as published by | |
* the Free Software Foundation, either version 3 of the License, or | |
* (at your option) any later version. | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* You should have received a copy of the GNU General Public License | |
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |
*/ | |
/** | |
* Enables or disables filtering for cross domain requests. | |
* Recommended value: true | |
*/ | |
define('CSAJAX_FILTERS', true); | |
/** | |
* If set to true, $valid_requests should hold only domains i.e. a.example.com, b.example.com, usethisdomain.com | |
* If set to false, $valid_requests should hold the whole URL ( without the parameters ) i.e. http://example.com/this/is/long/url/ | |
* Recommended value: false (for security reasons - do not forget that anyone can access your proxy) | |
*/ | |
define('CSAJAX_FILTER_DOMAIN', false); | |
/** | |
* Enables or disables Expect: 100-continue header. Some webservers don't | |
* handle this header correctly. | |
* Recommended value: false | |
*/ | |
define('CSAJAX_SUPPRESS_EXPECT', false); | |
/** | |
* Set debugging to true to receive additional messages - really helpful on development | |
*/ | |
define('CSAJAX_DEBUG', true); | |
define('LOG_FILE', __DIR__ . DIRECTORY_SEPARATOR . date("Y-m-d") . '.log'); | |
/** | |
* A set of valid cross domain requests | |
*/ | |
$valid_requests = array( | |
'localhost', | |
'localhost:9000', | |
'https://localhost', | |
'https://localhost:9000' | |
); | |
debug("valid_requests: " . print_r($valid_requests, true)); | |
/** | |
* Set extra multiple options for cURL | |
* Could be used to define CURLOPT_SSL_VERIFYPEER & CURLOPT_SSL_VERIFYHOST for HTTPS | |
* Also to overwrite any other options without changing the code | |
* See http://php.net/manual/en/function.curl-setopt-array.php | |
*/ | |
$curl_options = array( | |
CURLOPT_SSL_VERIFYPEER => false, | |
CURLOPT_SSL_VERIFYHOST => 0, | |
); | |
/* * * STOP EDITING HERE UNLESS YOU KNOW WHAT YOU ARE DOING * * */ | |
// identify request headers | |
$request_headers = array( ); | |
if (function_exists('getallheaders')) { | |
$allHeaders = getallheaders(); | |
debug("getallheaders Array: " . print_r($allHeaders, true)); | |
if($allHeaders && (count($allHeaders) > 0)) { | |
foreach ($allHeaders as $key => $value) { | |
$request_headers[] = "$key: $value"; | |
} | |
} | |
} | |
if(count($request_headers) == 0) { | |
debug("Iterating SERVER Array for extracting headers."); | |
debug("Server Array: " . print_r($_SERVER, true)); | |
foreach ($_SERVER as $key => $value) { | |
if (strpos($key, 'HTTP_') === 0 || strpos($key, 'CONTENT_') === 0) { | |
$headername = str_replace('_', ' ', str_replace('HTTP_', '', $key)); | |
$headername = str_replace(' ', '-', ucwords(strtolower($headername))); | |
if (!in_array($headername, array( 'Host', 'X-Proxy-Url' ))) { | |
$request_headers[] = "$headername: $value"; | |
} | |
} | |
} | |
} | |
debug("SERVER Array: " . print_r($_SERVER, true)); | |
debug("Request headers array " . print_r($request_headers, true)); | |
// identify request method, url and params | |
$request_method = $_SERVER['REQUEST_METHOD']; | |
if ('GET' == $request_method) { | |
$request_params = $_GET; | |
} elseif ('POST' == $request_method) { | |
$request_params = $_POST; | |
if (empty($request_params)) { | |
$data = file_get_contents('php://input'); | |
if (!empty($data)) { | |
$request_params = $data; | |
} | |
} | |
} elseif ('PUT' == $request_method || 'DELETE' == $request_method) { | |
$request_params = file_get_contents('php://input'); | |
} else { | |
$request_params = null; | |
} | |
debug("Request Method " . $request_method); | |
debug("Request Params " . print_r($request_params, true)); | |
// Get URL from `csurl` in GET or POST data, before falling back to X-Proxy-URL header. | |
if (isset($_REQUEST['csurl'])) { | |
$request_url = urldecode($_REQUEST['csurl']); | |
} elseif (isset($_SERVER['HTTP_X_PROXY_URL'])) { | |
$request_url = urldecode($_SERVER['HTTP_X_PROXY_URL']); | |
} else { | |
header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); | |
header('Status: 404 Not Found'); | |
$_SERVER['REDIRECT_STATUS'] = 404; | |
exit; | |
} | |
debug("Request URL " . $request_url); | |
$p_request_url = parse_url($request_url); | |
debug("Parsed Request URL " . print_r($p_request_url, true)); | |
// csurl may exist in GET request methods | |
if (is_array($request_params) && array_key_exists('csurl', $request_params)) { | |
unset($request_params['csurl']); | |
} | |
debug("Parsed Request Params after removing csurl " . print_r($request_params, true)); | |
// ignore requests for proxy :) | |
if (preg_match('!' . $_SERVER['SCRIPT_NAME'] . '!', $request_url) || empty($request_url) || count($p_request_url) == 1) { | |
error('Invalid request - make sure that csurl variable is not empty'); | |
exit; | |
} | |
// check against valid requests | |
if (CSAJAX_FILTERS) { | |
$parsed = $p_request_url; | |
if (CSAJAX_FILTER_DOMAIN) { | |
if (!in_array($parsed['host'], $valid_requests)) { | |
error('Invalid domain - ' . $parsed['host'] . ' does not included in valid requests'); | |
exit; | |
} | |
} else { | |
$check_url = isset($parsed['scheme']) ? $parsed['scheme'] . '://' : ''; | |
$check_url .= isset($parsed['user']) ? $parsed['user'] . ($parsed['pass'] ? ':' . $parsed['pass'] : '') . '@' : ''; | |
$check_url .= isset($parsed['host']) ? $parsed['host'] : ''; | |
$check_url .= isset($parsed['port']) ? ':' . $parsed['port'] : ''; | |
//$check_url .= isset($parsed['path']) ? $parsed['path'] : ''; | |
if (!in_array($check_url, $valid_requests)) { | |
debug('Invalid domain - ' . $request_url . ' does not included in valid requests'); | |
exit; | |
} | |
} | |
} | |
debug("Parsed Request URL passed the Valid Domain check: " . print_r($p_request_url, true)); | |
// append query string for GET requests | |
if ($request_method == 'GET' && count($request_params) > 0 && (!array_key_exists('query', $p_request_url) || empty($p_request_url['query']))) { | |
$request_url .= '?' . http_build_query($request_params); | |
} | |
debug("Request URL has passed the Valid Domain check: " . $request_url); | |
// let the request begin | |
$ch = curl_init($request_url); | |
debug("Initiating CURL call for the request url."); | |
// Suppress Expect header | |
if (CSAJAX_SUPPRESS_EXPECT) { | |
array_push($request_headers, 'Expect:'); | |
} | |
curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers); // (re-)send headers | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // return response | |
curl_setopt($ch, CURLOPT_HEADER, true); // enabled response headers | |
if(array_key_exists('CONTENT_TYPE', $_SERVER) && strpos($_SERVER['CONTENT_TYPE'], 'multipart/form-data;') === 0) { | |
debug("Request has Multipart Files: " . print_r($_FILES, true)); | |
$filesList = $_FILES; | |
if(empty($request_params)) { | |
$request_params = array(); | |
} | |
foreach ($filesList as $key => $fileProps) { | |
$request_params[$key] = new CurlFile($fileProps['tmp_name'], $fileProps['type'], $fileProps['name']); | |
} | |
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true); | |
debug("Request Params with CurlFile(s): " . print_r($request_params, true)); | |
} | |
// add data for POST, PUT or DELETE requests | |
if ('POST' == $request_method) { | |
$post_data = is_array($request_params) ? http_build_query($request_params) : $request_params; | |
curl_setopt($ch, CURLOPT_POST, true); | |
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); | |
} elseif ('PUT' == $request_method || 'DELETE' == $request_method) { | |
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request_method); | |
curl_setopt($ch, CURLOPT_POSTFIELDS, $request_params); | |
} | |
debug("Initiating CURL $request_method call with data: " . print_r($request_params, true)); | |
// Set multiple options for curl according to configuration | |
if (is_array($curl_options) && 0 <= count($curl_options)) { | |
curl_setopt_array($ch, $curl_options); | |
} | |
// retrieve response (headers and content) | |
$response = curl_exec($ch); | |
curl_close($ch); | |
debug("Response Received from CURL: " . print_r($response, true)); | |
if(empty($response)) { | |
error("No Response received from Server! Pls check if Backend Service is running!"); | |
exit(); | |
} | |
// split response to header and content | |
list($response_headers, $response_content) = preg_split('/(\r\n){2}/', $response, 2); | |
debug("Response Headers received from Back End: " . $response_headers); | |
debug("Response Content received from Back End: " . $response_content); | |
debug("Iterating the Response Headers received from Back End."); | |
// (re-)send the headers | |
$response_headers = preg_split('/(\r\n){1}/', $response_headers); | |
foreach ($response_headers as $key => $response_header) { | |
debug("key " . $key); | |
debug("header " . $response_header); | |
// Rewrite the `Location` header, so clients will also use the proxy for redirects. | |
if (preg_match('/^Location:/', $response_header)) { | |
list($header, $value) = preg_split('/: /', $response_header, 2); | |
$response_header = 'Location: ' . $_SERVER['REQUEST_URI'] . '?csurl=' . $value; | |
} | |
if (!preg_match('/^(Transfer-Encoding):/', $response_header)) { | |
header($response_header, false); | |
} | |
} | |
// finally, output the content | |
print($response_content); | |
function format($msg, $level = 'MSG', $newline = true) | |
{ | |
$datetime = date("Y-m-d H:i:s"); | |
$message = "$datetime [$level] $msg"; | |
if ($newline) { | |
$message = $message . PHP_EOL; | |
} | |
return $message; | |
} | |
function logger($msg, $level = 'MSG', $newline = true) | |
{ | |
if (CSAJAX_DEBUG == false) { | |
return false; | |
} | |
$output = LOG_FILE; | |
$message = format($msg, $level, $newline); | |
if (!$fp = @fopen($output, 'ab')) { | |
header('Failed to create the log file!'); | |
$_SERVER['REDIRECT_STATUS'] = 500; | |
exit; | |
//return false; | |
} | |
flock($fp, LOCK_EX); | |
fwrite($fp, $message); | |
flock($fp, LOCK_UN); | |
fclose($fp); | |
return true; | |
} | |
function error($msg, $newline = true) | |
{ | |
logger($msg, 'ERROR', $newline); | |
} | |
function debug($msg, $newline = true) | |
{ | |
logger($msg, 'DEBUG', $newline); | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment