I'm trying to develop a kind of Browser with PHP
.
So far my class
can process a GET
or a POST
request with this Content Type
: application/x-www-form-urlencoded
.
Now I need to move to a JSON
one. I've set the Content-Type
header to application/json
.
The fact is, with this type I got the following issue: Setting up a POST request will result in a GET request. This is really weird.
Here is my code:
private function request($url, $reset_cookies, $post_data = null, $custom_headers = null)
{
// Create options
$options = array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_HEADER => 0,
CURLINFO_HEADER_OUT => 1,
CURLOPT_FAILONERROR => 1,
CURLOPT_USERAGENT => $this->user_agent,
CURLOPT_CONNECTTIMEOUT => 30,
CURLOPT_TIMEOUT => 30,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_MAXREDIRS => 10,
CURLOPT_AUTOREFERER => 1,
CURLOPT_COOKIESESSION => $reset_cookies ? 1 : 0,
CURLOPT_COOKIEJAR => $this->cookies_file,
CURLOPT_COOKIEFILE => $this->cookies_file,
CURLOPT_HTTPHEADER => array('Accept-language: en'),
// SSL
/*
CURLOPT_SSL_CIPHER_LIST => 'TLSv1',
CURLOPT_SSL_VERIFYPEER => 1,
CURLOPT_CAINFO => dirname(__FILE__) . '/Entrust.netCertificationAuthority(2048).crt',
*/
);
// Add headers
if (isset($custom_headers)) $options[CURLOPT_HTTPHEADER] = array_merge($options[CURLOPT_HTTPHEADER], $custom_headers);
// Add POST data
if (isset($post_data))
{
$options[CURLOPT_POST] = 1;
$options[CURLOPT_POSTFIELDS] = is_string($post_data) ? $post_data : http_build_query($post_data);
}
// Attach options
curl_setopt_array($this->curl, $options);
// Execute the request and read the response
$content = curl_exec($this->curl);
print_r($options);
print_r(curl_getinfo($this->curl, CURLINFO_HEADER_OUT));
// Clean local variables
unset($url);
unset($reset_cookies);
unset($post_data);
unset($custom_headers);
unset($options);
// Handle any error
if (curl_errno($this->curl))
{
unset($content);
throw new Exception(curl_error($this->curl));
}
return $content;
}
To illustrate my issue, here is an example:
CUrl
options as an Array
:
Array
(
[10002] => http://mywebsite.com/post/
[19913] => 1
[42] => 0
[2] => 1
[45] => 1
[10018] => Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
[78] => 30
[13] => 30
[52] => 1
[68] => 10
[58] => 1
[96] => 0
[10082] => C:\wamp\www\v2\_libs/../_cookies/14d0fd2b-9f15-4ac5-8fae-4246cc6cef49.cookie
[10031] => C:\wamp\www\v2\_libs/../_cookies/14d0fd2b-9f15-4ac5-8fae-4246cc6cef49.cookie
[10023] => Array
(
[0] => Accept-language: en
[1] => RequestVerificationToken: 4PMxvJsQzFJ5oFt3JdUPe6Bp_geIj4obDJCYIRoU09PrrfcBSUgJT9iB3mXnGFc2KSlYrPcRHF7iHdQhGNu0GKLUzd5FywfaADbGS8wjhXraF36W0
[2] => Content-Type: application/json
)
[47] => 1
[10015] => {"usernameOrFeedId":"manitoba","feed_message_body":"Dummy message goes here"}
)
So the request header seems good to me, but I may be wrong.
And here is the real
header sent by CUrl
:
GET /post/ HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Host: mywebsite.com
Accept: */*
Referer: http://mywebsite.com/post/
Cookie: ADRUM_BT=R%3a53%7cclientRequestGUID%3a9787a51b-b24d-4400-9d6a-efbd618c74c0%7cbtId%3a18790%7cbtERT%3a44; CSRFToken=o_eoIVji7pWclOsrLaJpZEbOFSBJBm851rHbH0Xqwdzw2tC5j07EAc23mlj-opWowgpj0RkHyiktl1cS6onBqI43afM1; WebSessionId=3aem0m2xpwmvesgphna5gaop; prod=rd101o00000000000000000000ffff0a5a2a74o80; AuthenticateCookie=AAAAAtsQgeb8+UXrJ+wa7CGVJKnqizEAo2bMuFvqvwYMAl1NRaa6z68LBRx9hiHzPBC8tYqiayHID6pHChGXB7VywemwTpGivcRQ3nRlUVuaYQKyxQt21p1mx7OMlLCsRA==; web_lang.prod=fr
Accept-language: en
RequestVerificationToken: 4PMxvJsQzFJ5oFt3JdUPe6Bp_geIj4obDJCYIRoU09PrrfcBSUgJT9iB3mXnGFc2KSlYrPcRHF7iHdQhGNu0GKLUzd5FywfaADbGS8wjhXraF34W0
Content-Type: application/json
As you can see, it's a GET
request and the post data look to have disapeared.
Am I doing it wrong ?
You're following redirects, that means you get a 3xx response code and curl makes a second request to the new URL.
curl will act according to the specific 3xx code and for some of the redirects it will change request method from POST to GET - enabling VERBOSE will show you if it does so or not. The response codes that makes curl change method are 301, 302 and 303. It does so because that's how browsers act on those response codes.
libcurl offers an option called CURLOPT_POSTREDIR that you can use to tell curl to not change method for specific HTTP responses. Using that, you can thus have curl send a POST even after redirecting with one of these response codes.
CURLOPT_FOLLOWLOCATION
seems to be the cause shown by
Referer: http://mywebsite.com/post/
seems the server is doing a PRG ?
http://en.wikipedia.org/wiki/Post/Redirect/Get
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With