Reputation: 12522
I have a piece of code that does a post http request using curl and returns an output. The website I'm making a post request to has a redirect from http to https.
When I do a post request to https port, everything works fine. when I do the same request to the http port (and get redirected to https port) I get an empty string. Please, could anyone tell me why is it not working and how to do it correctly.
The function that does a post request:
function curl_query($url, $username, $password, $payload) {
$additionalHeaders = "";
$process = curl_init($url);
curl_setopt($process, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded',$additionalHeaders));
curl_setopt($process, CURLOPT_HEADER, false);
curl_setopt($process, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($process, CURLOPT_TIMEOUT, 30);
curl_setopt($process, CURLOPT_POST, 1);
curl_setopt($process, CURLOPT_POSTFIELDS, $payload);
curl_setopt($process, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($process, CURLOPT_MAXREDIRS, 4);
curl_setopt($process, CURLOPT_RETURNTRANSFER, true);
curl_setopt($process, CURLOPT_SSL_VERIFYPEER, false);
$return = curl_exec($process);
return $return;
}
A .htaccess entry that redirects a query from port 80 to port 443:
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
UPDATE After some debugging I've found that after the initial POST and being redirected to a new location curl is sending a GET request. Is it possible to make it resend the initial POST to a new location?
Upvotes: 4
Views: 5664
Reputation: 670
Use "CURLOPT_UNRESTRICTED_AUTH: true" to keep sending auth parameters to the redirected request.
Use "CURLOPT_POSTREDIR: true" to keep sending POST type request with POST parameters to the redirected request.
These options are described in @Arthur link: http://php.net/manual/en/function.curl-setopt.php
Upvotes: 0
Reputation: 634
Ran into the same issue today and first thought it was a bug of curl. However after digging into it a bit more I found out that RFC 2616 states the following about redirecting POST requests:
301 - Moved Permanently:
If the 301 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.
Note: When automatically redirecting a POST request after receiving a 301 status code, some existing HTTP/1.0 user agents will erroneously change it into a GET request.
So knowing that curl cannot ask the user anything it seems reasonable that for 301 and 302 redirects POST is turned into GET (even though this is not 100% according to RFC).
Luckily since curl 7.19.1 (php 5.3.2) there is the option to force curl into keeping POST method for redirects:
CURLOPT_POSTREDIR
A bitmask of 1 (301 Moved Permanently), 2 (302 Found) and 4 (303 See Other) if the HTTP POST method should be maintained when CURLOPT_FOLLOWLOCATION is set and a specific type of redirect occurs.
http://php.net/manual/en/function.curl-setopt.php
So example:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_POSTREDIR, 7);
$response = curl_exec($ch);
curl_close($ch);
Upvotes: 2