I have a PHP page, main.php which is on server 1.
I have a PHP page main.php (same page, different code) on server 2.
main.php is a WebService.
I would l
If you have access to the Apache server config you can create a virtualhost with the following settings:
ProxyPreserveHost Off
ProxyPass / http://remotesite.domain.tld/
ProxyPassReverse / http://remotesite.domain.tld/
ProxyPassReverseCookieDomain remotesite.domain.tld proxysite.tld
You'll need to enable mod_proxy and mod_proxy_http for this. Substitute remotesite.domain.tld to the site you forward to, and proxysite.tld to the forwarder.
If you don't have access to the server config files, you can still do in php, by manually setting up curl and forward everything.
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
/* Set it true for debugging. */
$logHeaders = FALSE;
/* Site to forward requests to. */
$site = 'http://remotesite.domain.tld/';
/* Domains to use when rewriting some headers. */
$remoteDomain = 'remotesite.domain.tld';
$proxyDomain = 'proxysite.tld';
$request = $_SERVER['REQUEST_URI'];
$ch = curl_init();
/* If there was a POST request, then forward that as well.*/
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $_POST);
}
curl_setopt($ch, CURLOPT_URL, $site . $request);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
$headers = getallheaders();
/* Translate some headers to make the remote party think we actually browsing that site. */
$extraHeaders = array();
if (isset($headers['Referer']))
{
$extraHeaders[] = 'Referer: '. str_replace($proxyDomain, $remoteDomain, $headers['Referer']);
}
if (isset($headers['Origin']))
{
$extraHeaders[] = 'Origin: '. str_replace($proxyDomain, $remoteDomain, $headers['Origin']);
}
/* Forward cookie as it came. */
curl_setopt($ch, CURLOPT_HTTPHEADER, $extraHeaders);
if (isset($headers['Cookie']))
{
curl_setopt($ch, CURLOPT_COOKIE, $headers['Cookie']);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
if ($logHeaders)
{
$f = fopen("headers.txt", "a");
curl_setopt($ch, CURLOPT_VERBOSE, TRUE);
curl_setopt($ch, CURLOPT_STDERR, $f);
}
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($response, 0, $header_size);
$body = substr($response, $header_size);
$headerArray = explode(PHP_EOL, $headers);
/* Process response headers. */
foreach($headerArray as $header)
{
$colonPos = strpos($header, ':');
if ($colonPos !== FALSE)
{
$headerName = substr($header, 0, $colonPos);
/* Ignore content headers, let the webserver decide how to deal with the content. */
if (trim($headerName) == 'Content-Encoding') continue;
if (trim($headerName) == 'Content-Length') continue;
if (trim($headerName) == 'Transfer-Encoding') continue;
if (trim($headerName) == 'Location') continue;
/* -- */
/* Change cookie domain for the proxy */
if (trim($headerName) == 'Set-Cookie')
{
$header = str_replace('domain='.$remoteDomain, 'domain='.$proxyDomain, $header);
}
/* -- */
}
header($header, FALSE);
}
echo $body;
if ($logHeaders)
{
fclose($f);
}
curl_close($ch);
?>
EDIT:
And of course the script must be in the root directory of a (sub)domain. And you should have a .htaccess that rewrites everything to it:
RewriteEngine On
RewriteRule .* index.php
this is the solution i have found (there might be better)
public static function getResponse ($url,$headers,$body)
{
$params = '?' . http_build_query($headers);
$redirect_url = $url . $params;
$ch = curl_init($redirect_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
if (!isset($response))
return null;
return $response;
}
I have used the code by Rehmat and Calmarius and made a few changes so now it handles multiple fields with same name like
<input type="text" name="example[]">
<input type="text" name="example[]">
<input type="text" name="example[]">
and to upload files too, including multiple files that use the same field name.
here is goes:
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
class proxy {
private $logHeaders = false;
/* Site to forward requests to. */
private $site = 'http://redirectToSite';
/* Domains to use when rewriting some headers. */
private $remoteDomain = 'redirectToSite';
private $proxyDomain = 'yourproxydomain.com';
public function __construct() {
$request = $_SERVER['REQUEST_URI'];
$ch = curl_init();
/* If there was a POST request, then forward that as well.*/
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$post = $this->sanitizePostFields($_POST);
$files = $this->sanitizeFiles($_FILES);
if ($files) {
$post = array_merge($post, $files);
}
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
/*
// this is enough if not uploading files
curl_setopt(
$ch,
CURLOPT_POSTFIELDS,
http_build_query($_POST)
);
*/
}
curl_setopt($ch, CURLOPT_URL, $this->site . $request);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
$headers = getallheaders();
/*
Translate some headers to make the remote party think we
actually browsing that site.
*/
$extraHeaders = array();
if (isset($headers['Referer'])) {
$extraHeaders[] = 'Referer: '. str_replace(
$this->proxyDomain,
$this->remoteDomain,
$headers['Referer']
);
}
if (isset($headers['Origin'])) {
$extraHeaders[] = 'Origin: '. str_replace(
$this->proxyDomain,
$this->remoteDomain,
$headers['Origin']
);
}
/*
Forward cookie as it came.
*/
curl_setopt($ch, CURLOPT_HTTPHEADER, $extraHeaders);
if (isset($headers['Cookie'])) {
curl_setopt($ch, CURLOPT_COOKIE, $headers['Cookie']);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
if ($this->logHeaders) {
$f = fopen("headers.txt", "a");
curl_setopt($ch, CURLOPT_VERBOSE, TRUE);
curl_setopt($ch, CURLOPT_STDERR, $f);
}
//curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($ch);
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($response, 0, $header_size);
$body = substr($response, $header_size);
$headerArray = explode(PHP_EOL, $headers);
/* Process response headers. */
foreach($headerArray as $header) {
$colonPos = strpos($header, ':');
if ($colonPos !== FALSE) {
$headerName = substr($header, 0, $colonPos);
/*
Ignore content headers, let the webserver decide how to
deal with the content.
*/
if (trim($headerName) == 'Content-Encoding') continue;
if (trim($headerName) == 'Content-Length') continue;
if (trim($headerName) == 'Transfer-Encoding') continue;
//if (trim($headerName) == 'Location') continue;
/* -- */
/* Change cookie domain for the proxy */
if (trim($headerName) == 'Set-Cookie') {
$header = str_replace(
'domain='.$this->remoteDomain,
'domain='.$this->proxyDomain,
$header
);
}
/* -- */
if (trim($headerName) == 'Location') {
$header = str_replace(
$this->remoteDomain,
$this->proxyDomain,
$header
);
}
}
header($header, FALSE);
}
echo $body;
if ($this->logHeaders) {
fclose($f);
}
curl_close($ch);
}
private function sanitizePostFields($post, $fieldName = '') {
if (empty($post)) { return false; }
if (!is_array($post)) { return false; }
$result = [];
foreach ($post as $k => $v) {
if (is_string($v)) {
$result[($fieldName ? "{$fieldName}[{$k}]" : $k)] = $v;
}
elseif (is_array($v)) {
$result = array_merge(
$result,
$this->sanitizePostFields($v, $k)
);
}
}
return $result;
}
private function sanitizeFiles($files) {
if (empty($files)) { return false; }
if (!is_array($files)) { return false; }
$result = [];
foreach ($files as $k => $v) {
if (empty($v['name'])) { continue; }
if (is_array($v['name'])) {
// more than one file using the same name field[]
$nFields = count($v['name']);
for ($i = 0; $i < $nFields; $i++) {
if (empty($v['tmp_name'][$i])) { continue; }
$curl_file_upload = new CURLFile(
$v['tmp_name'][$i],
$v['type'][$i],
$v['name'][$i]
);
$result["{$k}[{$i}]"] = $curl_file_upload;
}
}
else {
$curl_file_upload = new CURLFile(
$v['tmp_name'],
$v['type'],
$v['name']
);
$result[$k] = $curl_file_upload;
}
}
return $result;
}
}
$proxy = new proxy();