What is the curl_setopt equivalent of exec('curl -k ...') - php

I am trying duplicate the functionality of this command:
exec('curl -k -d "pameters=here" https://apiurlhere.com', $output);
with curl_exec():
$url = 'https://apiurlhere.com?parameters=here';
$ci = curl_init();
curl_setopt($ci, CURLOPT_POST, TRUE);
curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ci, CURLOPT_URL, $url);
$response = curl_exec($ci);
curl_close ($ci);
print_r($response);
I have been trying the different options found in the docs (http://php.net/manual/en/function.curl-setopt.php), and thought it was CURLOPT_SSL_VERIFYPEER, but it still failed (response comes back empty).
The URL i'm posting to uses SNI which is causing cURL to fail when the SSL cert returns a different host name than it's expecting.
Is there a curl_setopt equivalent to -k?

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE) is the equivalent of -k on the command line (which you shouldn't really use, since it makes the connection vulnerable to MITM attacks).
Your problem here is that you're assuming that -d "pameters=here" is equivalent to putting these parameters in the URL query like this https://apiurlhere.com?parameters=here.
This isn't the case, see documentation for -d:
(HTTP) Sends the specified data in a POST request to the HTTP server, in the same way that a browser does when a user has
filled in an HTML form and presses the submit button. This will cause
curl to pass the data to
the server using the content-type application/x-www-form-urlencoded.
You should probably use POSTFIELDS for this:
curl_setopt($ch, CURLOPT_POSTFIELDS, array("parameters" => "here"));

Try that :
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
See http://www.php.net/manual/en/function.curl-setopt.php

Related

Different answers to the same queries cUrl (Steam Market)

When in the browser you follow the link:
http://steamcommunity.com/market/priceoverview/?country=US%C2%A4cy=5&appid=570&market_hash_name=Gem%20of%20Taegeuk
Gives out { "success": false }, In headings 500 a mistake. But when I do the same inquiry through cUrl
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://steamcommunity.com/market/priceoverview/?country=US&currency=5&appid=570&market_hash_name=Gem%20of%20Taegeuk");
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
$curl = curl_exec($ch);
In response, instead of json I get this:
‹ЄV*.MNN-.VІJKМ)N­яятКC4
Tell me how to fix this and what might be the cause of the error (500)?
The server return gzipped response (header Content-Encoding: gzip). So, you need auto encoding:
curl_setopt($ch,CURLOPT_ENCODING, '');
P.S. Browser unlike the curl unpacks the response automatically.
Two problems:
1) There's an additional %C2%A4cy% and missing curren after country=US in the example link. The URL in CURL looks ok.
2) Your CURL commands do not follow redirects, the URL should be with https:// (browser does that automatically). You can follow redirects with curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

I need help converting a successful request from Postman into CURL commands using PHP (involves HTTPS and POST)

The endpoint I'm trying to reach requires HTTPS and Basic Authentication. My team was given an API key, and the documentation states to use the key as the username, and to leave the password blank.
Here is the example CURL request from the documentation:
curl -i -k -u '<api_key>': -XPOST --data-urlencode data#/path/to/test/file.json "https://<your_subdomain>.vendor.org/api/v1/assessments/import"; echo ""
When I execute the following using the Postman extension for Chrome, I get a successful response from the server:
I'm trying to execute this locally using PHP (XAMPP install). The following is getting a response from the server saying the username/password is incorrect:
function curlPost($url, $headers, $username, $password, $data) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CAINFO, 'certificate.pem');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
print_r(curl_exec($ch));
// print_r(curl_getinfo($ch));
// print_r(curl_error($ch));
curl_close($ch);
}
$data = '{"key":"value", "key":"value"}';
curlPost('https://domain.com/api/data', ['Content-Type: application/xml'], 'api_key', '', $data);
{"success":false,"errors":["Email\/Username or password incorrect. Please try again."],"warnings":[],"info":[],"meta":[],"results":[]}
The JSON string used in $data was copied and pasted from a successful Postman request.
The certificate.pem is in the same folder as the script, and read/write permissions have been given to everyone. I have tried exporting the specific certificate for our vendor's site from my machine as well as the CA bundle linked in the top response to this post. I was able to use it to successfully hit the vendor's api-key-test endpoint via PHP/CURL.
I'm pretty new to this. Would you mind helping me wrap my head around what I'm missing? While I've copied and pasted a ton, the function is largely my own. The parameter for headers will be used for other things.
Basic Authentication with the HTTP Authorization header uses the Base64 encoded value of "username:password" (without the double quotes)
So I'm assuming in your case you would need to Base64 encode "yourApiKeyValue:" and put that in a Authorization header in your cURL command
MDN reference - HTTP Authentication
Edit: This may also be helpful
How do I make a request using http basic authentication-with-php-curl

setup cURL for SSL

Once again, another question concerning cURL and SSL, as I cannot find matching answers to my problem.
I have working SSL on my webserver, with trusted cert and green signs on browsers address bar a.s.o., NOT self signed. So good, so far.
Now I want communicate with cURL and use the following function (POST data not added yet):
function ssltest(){
$post_data = '';
$url = 'https://myserver/test.php';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_MUTE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
//curl_setopt($ch, CURLOPT_CAINFO, 'sslstuff/cacert.pem');
curl_setopt($ch, CURLOPT_CAINFO, 'sslstuff/false.pem');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
echo ssltest();
As the cacert.pem I use this one, which I found in my browser, which is obviously identical to what I found here http://curl.haxx.se/ca/cacert.pem
In the code shown above there is a false.pem to be seen. Now what ? If this file is empty, there's no response from Server, but I tested to paste the cert from another enterprise from the list on curl.haxx.se I get the same correct answer from the server as result, as when I use my correct .pem
What's the issue ? What I am missing ?
"there's no response from Server"
I think that's very unlikely. I suspect there is no HTTP response from the server, but that the SSL negotiation is failing - but you've got no error checking in your code. If $output===false, have a look at curl_error().
You might want to play around with VERIFYHOST and VERIFYPEER to pin down the exact cause of the problem.

cURL to get response from Google Safe Browsing Lookup

I'm trying to get response using the Google Safe Browsing Lookup API like this:
$url ="https://sb-ssl.google.com/safebrowsing/api/lookup?client=myappname&apikey=mykey&appver=1.0&pver=3.0&url=".urlencode($myurl);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);
$body = curl_exec($ch);
$info = curl_getinfo($ch);
I know that my URL is correct since if I dump it and then paste it to the browser I get the expected result (for example 'malware').
So I am assuming it must be something with cURL. I'm working on localhost and extension=php_curl.dll is un-commented in my php.ini, Php version 5.4.4
The html_code is always 0
Simply set CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST to false.
Anything wrong with my cURL code (http status of 0)?
Also check http://code.google.com/p/twitter-api/issues/detail?id=1291 , it might help. It is different APIs, but with the same problem anyway.
The problem and its solution is very nicely described here:
http://richardwarrender.com/2007/05/the-secret-to-curl-in-php-on-windows/
Basically if you are not using a standalone version of cURL the chances are that the cURL functions do not include a certificate bundle which was needed in my case since I was trying to connect to secure host.
$ch = curl_init();
// Apply various settings
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_CAINFO, "C:/xampp/ca-bundle.crt"); //path to the CA-bundle
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec ($ch);
curl_close($ch);

curl CLI to curl PHP

I use the following command in some old scripts:
curl -Lk "https:www.example.com/stuff/api.php?"
I then record the header into a variable and make comparisons and so forth. What I would really like to do is convert the process to PHP. I have enabled curl, openssl, and believe I have everything ready.
What I cannot seem to find is a handy translation to convert that command line syntax to the equivalent commands in PHP.
I suspect something in the order of :
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
// What goes here so that I just get the Location and nothing else?
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// Get the response and close the channel.
$response = curl_exec($ch);
curl_close($ch);
The goal being $response = the data from the api “OK=1&ect”
Thank you
I'm a little confused by your comment:
// What goes here so that I just get the Location and nothing else?
Anyway, if you want to obtain the response body from the remote server, use:
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
If you want to get the headers in the response (i.e.: what your comment might be referring to):
curl_setopt($ch, CURLOPT_HEADER, 1);
If your problem is that there is a redirection between the initial call and the response, use:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);

Categories