Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP, How to Redirect/Forward HTTP Request with header and body?

Tags:

php

curl

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 like to forward the full HTTP request made to server 1, to server 2, so that when a user sends an HTTP request to main.php (server 1), it would get the response from main.php on server 2.

I would like the request made to server 2 to be exactly like the original request to server 1.

I take the Http Request data via:

$some_param  = $_REQUEST['param'] $body =file_get_contents('php://input'); 

and lets say i have

$server1_url = "11111"; $server2_url = "22222"; 

The motivation for this is, i have a production server and a staging server, i would like to direct some traffic to the new server to test the new functionality on the staging server.

How do i redirect the request with all the data or "cloning" the full request, sending it to the new server and returning the new response?

Thanks for your help!

p.s i tried using php curl, but i dont understand how it works, also i found all kinds of answers, but none forward the Requests params and the body.

Again thanks!

like image 931
user2721348 Avatar asked Mar 16 '14 13:03

user2721348


People also ask

How can I redirect a URL to another URL in PHP?

To set a permanent PHP redirect, you can use the status code 301. Because this code indicates an indefinite redirection, the browser automatically redirects the user using the old URL to the new page address.

How do I forward a request in PHP?

Answer: Use the PHP header() Function You can simply use the PHP header() function to redirect a user to a different page. The PHP code in the following example will redirect the user from the page in which it is placed to the URL http://www.example.com/another-page.php . You can also specify relative URLs.

What PHP can do with header () command?

The header() function in PHP sends a raw HTTP header to a client or browser. Before HTML, XML, JSON, or other output is given to a browser or client, the server sends raw data as header information with the request (particularly HTTP Request).

Why PHP redirect is not working?

The root cause of this error is that php redirect header must be send before anything else. This means any space or characters sent to browser before the headers will result in this error. Like following example, there should not be any output of even a space before the headers are sent.


2 Answers

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 
like image 165
Calmarius Avatar answered Sep 20 '22 12:09

Calmarius


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;     } 
like image 37
user2721348 Avatar answered Sep 19 '22 12:09

user2721348