Skip to content

Instantly share code, notes, and snippets.

@Elavarasanlee
Created April 9, 2020 06:44
Show Gist options
  • Save Elavarasanlee/4cee04c7cdafa869e6e55383fab1813b to your computer and use it in GitHub Desktop.
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
<?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