3

Ok, so in my web app's API I have an incoming HTTP post request. I would like to pass that POST request on to a different server, without losing the data in the POST header. Is this possible? which type of redirect would I use? php examples?

Edit: The HTTP request is coming from a mobile app, not a web browser.

Thanks!

Kenny Winker
  • 11,919
  • 7
  • 56
  • 78

8 Answers8

9

You could use cURL or sockets to re-post the data, but you can't really redirect it.

POST'ing to a URL with cURL:

$ch = curl_init('http://www.somewhere.com/that/receives/postdata.php');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($_POST));
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
simshaun
  • 21,263
  • 1
  • 57
  • 73
  • +1. Doesn't deserve a downvote. Lots of people are recommending CURL as a potential workaround of this constraint. – coreyward Feb 08 '11 at 22:33
6
RewriteRule current-page.php http://www.newserver.com/newpage.php [NC,P]

The P on there (proxy) will preserve the POST data. You'll need to turn on the apache proxy module if it isn't already.

profitphp
  • 8,104
  • 2
  • 28
  • 21
  • I'm quite skeptical on this one. Have a working example somewhere I could see? **Edit:** I see you mention proxy... does Apache then proxy in the results of that page? – Brad Feb 08 '11 at 22:31
  • 1
    @brad It will work, but ya, its a reverse proxy and as such it is going to go through apache, so its not much better than the cUrl solution. – profitphp Feb 08 '11 at 22:41
  • 4
    +1 This is the proper solution, PHP should have nothing to do with it. HTTP servers (such as Apache) & clients (such as Firefox) are designed to handle these cases, its part of the HTTP specification that they conform to. – Tyler Egeto Feb 08 '11 at 23:15
  • 1
    This isn't a very good solution at all. You want to proxy someone's site through your server? That doesn't work with SSL, and you are going to have issues with cookies, ref checkers, etc. – Brad Feb 09 '11 at 03:15
4

I know this is an old question but this may help people who stumble upon this question. You should be able to send an HTTP 307 response code to make the user agent redirect to the new url and continue to use the same method and data. This answer has more details

Community
  • 1
  • 1
GMihovics
  • 53
  • 6
1

If the client (ie the mobile app) HTTP library supports this, then you can return HTTP 307 from server which states that "the request should be repeated with another URI ... with the same method". This is essentially a temporary redirect but tells the client to use the the same method, a POST.

The client making the request must be able to respond accordingly to the HTTP 307 response and follow the redirection with the same method - for many libraries this may be an additional flag or setting.

robert_murray
  • 2,070
  • 17
  • 9
0

I used the following code to redirect a post. In my case I am using only application/octet-stream content type so make sure you take that into consideration.

$request = file_get_contents ( "php://input" ); 

$arrContextOptions=array(
        "http" => array(
                "method" => "POST",
                "header" =>
                'Content-Type: application/octet-stream'. "\r\n".
                'Content-Length: ' . strlen($request) . "\r\n",
                "content" => $request,
        ),
        "ssl"=>array(
                "allow_self_signed"=>true,
                "verify_peer"=>false,
        ),
);
$arrContextOptions = stream_context_create($arrContextOptions);


header ( "HTTP/1.1" );
header ( "Content-Type: application/octet-stream" );

$result =  file_get_contents('http://thenewaddress.yes.it.works', false, $arrContextOptions);

file_put_contents("php://output", $result);
0

You cannot tell a browser to make a post request through an HTTP header. The location header will redirect, but only for GET or HEAD requests.

You can work around this limitation by displaying a page with a hidden form with the method attribute set to POST and the action set to the URL you want the browser to post to, then automatically submit it on page load. Example:

<body onload="document.getElementById('form').submit();">
  <form id="form" action="http://example.com/form_handler.php" method="POST">
    <input type="hidden" name="param_1" value="data">
  </form>
</body>

Alternately, you can make the POST request on your server and then display the results.

coreyward
  • 77,547
  • 20
  • 137
  • 166
  • This is for a non-browser web app api. No javascript. – Kenny Winker Feb 09 '11 at 07:15
  • Also wouldn't work if the POST being redirected contains a file upload. You'd have to round-trip the file's contents, as well as encode it so as to not break, and stuff it into a hidden form field and/or textarea, forcing the client to upload it yet again. – Marc B Feb 15 '11 at 18:57
-1

I think the solution I'm about to go with is something like:

<?
$url = 'http://myserver.com/file.php';

foreach ($_POST as $key => $value) {
  $text .= (strlen($text) > 0 ? '&' : '');
  $text .= $key . '=' . $value;
}

header('Location: ' . $url . '?' . $text);
exit;
?>

Can anyone think of a reason why this is a bad idea?

Kenny Winker
  • 11,919
  • 7
  • 56
  • 78
-2

If you want to take data from a POST request and simply POST it to another server, then use cURL.

--or--

If you want to take data from a POST request and redirect the client to that other server while POSTing the data, then use this method...

Dynamically generate a form with all of the POST data. Something likes this...

echo "<form name=\"someform\" action=\"http://www.somewhereelse.com/someform.whatever\">";
foreach ($_POST as $key=>$value) {
    echo "<input type=\"hidden=\" name=\"" . htmlspecialchars($key) . "\" value=\"" . htmlspecialchars($value) . "\" />";
}
echo "</form>";

Then, submit that form with some JavaScript when the page is done loading...

document.forms['someform'].submit();
Brad
  • 159,648
  • 54
  • 349
  • 530
  • This is for a non-browser api... javascript is not an option. – Kenny Winker Feb 09 '11 at 07:16
  • 1
    -1 If I saw one of my developers implementing this HTML/JS solution we would need to have a serious talk. – Tyler Egeto Feb 09 '11 at 17:00
  • 3
    @Tyler, you got a better solution? I posted this before Kenny mentioned he wasn't using browsers. The proxy method is a *bad* idea, for the reasons I specified above. This whole question represents a bad idea to begin with. I simply noted the only way it is possible, but again, this won't work for Kenny as he isn't using a browser. I leave the answer up as it is a commonly asked question. – Brad Feb 09 '11 at 17:13