PHP, как перенаправить/переслать HTTP-запрос с заголовком и телом?
У меня есть страница PHP, main.php, которая находится на сервере 1.
У меня есть страница PHP main.php(та же самая страница, другой код) на сервере 2.
main.php - это WebService.
Я хотел бы перенаправить полный HTTP-запрос, сделанный на сервер 1, на сервер 2,
так что, когда пользователь отправляет HTTP-запрос на main.php(сервер 1), он получит ответ от main.php на сервере 2.
Я хотел бы, чтобы запрос, сделанный на сервер 2, был точно таким же, как исходный запрос на сервер 1.
Я беру данные запроса Http через:
$some_param = $_REQUEST['param']
$body =file_get_contents('php://input');
и скажем, что у меня
$server1_url = "11111";
$server2_url = "22222";
Мотивация в том, что у меня есть производственный сервер и промежуточный сервер, я бы хотел направить некоторый трафик на новый сервер, чтобы протестировать новые функции на промежуточном сервере.
Как перенаправить запрос со всеми данными или "клонировать" полный запрос, отправить его на новый сервер и вернуть новый ответ?
Спасибо за вашу помощь!
p.s я попытался использовать php curl, но я не понимаю, как это работает, также я нашел все виды ответов, но ни один не пересылает параметры Requests и тело.
Снова спасибо!
Ответы
Ответ 1
это решение, которое я нашел (может быть, лучше)
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;
}
Ответ 2
Если у вас есть доступ к конфигурации сервера Apache, вы можете создать виртуальный хост со следующими настройками:
ProxyPreserveHost Off
ProxyPass / http://remotesite.domain.tld/
ProxyPassReverse / http://remotesite.domain.tld/
ProxyPassReverseCookieDomain remotesite.domain.tld proxysite.tld
Для этого вам необходимо включить mod_proxy и mod_proxy_http.
Замените remotesite.domain.tld на сайт, на который вы перешли, и proxysite.tld отправителю.
Если у вас нет доступа к конфигурационным файлам сервера, вы все равно можете сделать это в php, вручную настроив завиток и переместить все.
<?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);
?>
ИЗМЕНИТЬ:
И, конечно, script должен находиться в корневом каталоге (под) домена.
И вы должны иметь .htaccess, который переписывает все:
RewriteEngine On
RewriteRule .* index.php