I try to make a post request with php and curl. Here is my code
//PHP 5.3.5 and curl: 7.18.2
$ch = curl_init();
if(!empty($save_cookie)){
curl_setopt($ch, CURLOPT_COOKIEJAR, $save_cookie);
curl_setopt($ch, CURLOPT_COOKIEFILE, $save_cookie);
}else{
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
}
curl_setopt($ch, CURLOPT_REFERER, $referer);
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
curl_setopt($ch, CURLOPT_URL, 'http://localhost/post.php');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $pars);
curl_setopt($ch, CURLOPT_HEADER, $header);
curl_setopt($ch, CURLOPT_NOBODY, !$body);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$postResult = curl_exec($ch);
if (curl_errno($ch)) {
return false;
}
curl_close($ch);
return $postResult;
In http://localhost/post.php, I write
print_r($_SERVER);
The result return of curl is always
[REQUEST_METHOD] => GET
Remove the CURLOPT_NOBODY option and it will work. Or place it above the CURLOPT_POST line.
I think I have encountered this once, when trying to get just the header of a response. Setting
curl_setopt($ch, CURLOPT_NOBODY, true);
effectively instructs curl to issue a HEAD request, which is not a POST request. I think there is no way to just get the header from a POST (and just drop the connection after receiving the header). As a side effect, setting CURLOPT_NOBODY to false sets the request type to GET...
Do you really need the CURLOPT_NOBODY flag?
Try to move the
curl_setopt($ch, CURLOPT_NOBODY, !$body);
line right before the
curl_setopt($ch, CURLOPT_POSTFIELDS, $pars);
line.
There's an interesting post at the curl/set_opt page, shedding some light on this behaviour:
If your POST data seems to be disappearing (POST data empty, request
is being handled by the server as a GET), try rearranging the order of
CURLOPT_POSTFIELDS setting with CURLOPT_NOBODY. CURLOPT_POSTFIELDS has
to come AFTER CURLOPT_NOBODY setting because if it comes after it
wipes out the header that tells your URL target that the
request is a POST not a GET.
Related
I am using curl in PHP to make a post request to a database. The request looks something like this:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, getenv('DATABASE_URL'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data, '', '&'));
$output = curl_exec($ch)
where $data is defined earlier. The request uses a token as verification, and if the token is invalid, the above $output is the error message
{"error":"You do not have permissions to use the API"}
which is good. So I want to catch that error to handle it properly further down the program, so I use curl_error($ch) to do so. The problem is, this returns the empty string which according to the documentation corresponds to no errors. I have also tried the curl_errno to count the numbers, but this returns 0 errors.
Can anyone see my mistake(s)?
I am submitting login form data using curl in php, and from what I've observed the login POST has no response - the lander page is loaded by a subsequent GET request. What I'd like to know is how I can make a POST using curl and then a GET? For reference, here's my current code:
$ch = curl_init('https://<my url>');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Accept: text/html',
));
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_POST, 2);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'my post fields');
$result = curl_exec($ch);
// I need to make a get request to get the loggedin page here!?
curl_setopt($ch, CURLOPT_URL, 'https:<another_url>');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 0);
$result = curl_exec($ch);
echo curl_errno($ch);
I'm currently getting an error 52 from my POST which is no response, which I think should be expected. The issue is, when I tried to make a GET, I also got errno 52. Also for a sanity check, I retrieved my post fields my grabbing the form data from the network data from chrome dev tools.
Thanks in advance for the help!
I am trying to login to a site using curl but for some reason when I use the print_r($login) to view the output, I always end up seeing the original login page without it being processed (it was supposed to return something like login success or fail), I think curl is not able to submit the form, any suggestion?
$user="something"; $pass="something";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, "username={$user}&password={$pass}");
curl_setopt($ch, CURLOPT_USERAGENT, "Something");
$login = curl_exec($ch);
print_r($login);
You need to add
curl_setopt($ch, CURLOPT_POST, TRUE);
To send POST content. Without it, your CURLOPT_POSTFIELDS will be ignored.
I try to login with curl to a SSL secured website but somehow I don't get it right.
The first curl connection retrieves the login form. An SSL issue in the beginning is resolved now. The fields used for authentication and all hidden fields are identified and used for the following POST. The cookie file is defined and the jar to read from as well. The cookie file is accessible and gets updated with each login attempt. A session cookie is successfully set by curl. The HTTPHEADER is removed to stop the request from hitting the 100 Continue wall. Curl is configured to follow up and to send a referer.
However, I still cannot find where the script gets stuck. Neither Curl nor PHP issue any error messages or warnings.
Here is the shortened script:
$ch = curl_init();
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); // remove Expect header to avoid 100 Continue situations
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla [abbreviated]');
curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__).'/cacert.pem');
curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__).'/cookie.hq.txt'); // write cookies
curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__).'/cookie.hq.txt'); // read cookies
curl_setopt($ch, CURLOPT_COOKIESESSION, 1);
curl_setopt($ch, CURLOPT_URL, 'https://the_url.jsp');
$data = curl_exec($ch);
$error= curl_error($ch);
if(!empty($error))
echo '<p>'.$error.'</p>';
else
echo '<p>ok</p>';
Now the script reads the form, fills in the credentials and POSTs it back using the same curl_init handle:
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $options);
$data = curl_exec($ch);
$error=curl_error($ch);
But all I get back is the same form again and the same session cookie or a new one depending on the CURLOPT_COOKIESESSION setting.
When I log in manually I notice that there are two more cookies set: LtpaToken and LtpaToken2 but I never see them appearing in the request headers printed by the script.
Manually submitting the form works even without Javascript aktivated. So there cannot be some JS magic modifying the form data under the hood before submitting it.
Obviously I am missing something here. Any ideas where I can look further?
Solved: Finally the issue was due to an encoding issue in the POST.
Initially the POST data was created from an array with http_build_query().
Now the POST data is simply concatenated and both keys and values are urlencoded separately:
$options.=urlencode($fieldName).'='.urlencode($element->getAttribute('value'));
Solved: Finally the issue was due to an encoding issue in the POST. Initially the POST data was created from an array with http_build_query(). Now the POST data is simply concatenated and both keys and values are urlencoded separately:
$options.=urlencode($fieldName).'='.urlencode($element->getAttribute('value'));
See below url:--
cURL login session
and try this:-
http://php.net/manual/en/function.curl-setopt.php
<?php
echo curl_grab_page("https://www.example.net/login.php", "https://www.example.net/", "username=foo&password=bar", "true", "null", "false");
// $url = page to POST data
// $ref_url = tell the server which page you came from (spoofing)
// $login = true will make a clean cookie-file.
// $proxy = proxy data
// $proxystatus = do you use a proxy ? true/false
function
curl_grab_page($url,$ref_url,$data,$login,$proxy,$proxystatus){
if($login == 'true') {
$fp = fopen("cookie.txt", "w");
fclose($fp);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie.txt");
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
curl_setopt($ch, CURLOPT_TIMEOUT, 40);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
if ($proxystatus == 'true') {
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, TRUE);
curl_setopt($ch, CURLOPT_PROXY, $proxy);
}
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_REFERER, $ref_url);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
ob_start();
return curl_exec ($ch); // execute the curl command
ob_end_clean();
curl_close ($ch);
unset($ch);
}
Simple script but does not seem to be posting the fields across correctly on the second server. The only difference in php info is NSS/3.12.7.0 and NSS/3.12.9.0. One is on https and the other is not, is there another option that I am missing here?
$ch=curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
$result=curl_exec($ch);
curl_close($ch);
Add this it will turn off SSL verification :
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);