cURL in PHP to extract json - api

I'm new to using the curl library in php. I have been experimenting with some APIs where I came across this command
curl -i -H "API-KEY:xxxxxx" https://www.experiment.com/api/v2/list/
The API-KEY is given. Request is GET. The return format is in JSON. The service is using REST. I created a small PHP script
$cSession = curl_init();
curl_setopt($cSession,CURLOPT_URL,"https://www.experiment.com/api/v2/list/");
curl_setopt($cSession, CURLOPT_HTTPHEADER, array("API-KEY: XXXXXXXXX"));
$result=curl_exec($cSession);
$result turns out to be false. Is there something I'm missing.
Thanks.

Related

Mailtrap API - Cannot send emails - "Unauthorized" API error

I am using Mailtrap's SMTP to send my development/test e-mails to a fake inbox.
Their SMTP server feature works well, but I'm now trying to implement their API v2 instead.
Every time I hit the https://send.api.mailtrap.io/api/send endpoint, I keep getting the following error:
{"errors":["Unauthorized"]}
More info
I have a Paid account and generated an API Token which has full Admin rights
Only the send.api.mailtrap.io/api/send endpoint fails, other endpoints such as mailtrap.io/accounts are working
I am getting the same error whether I use their API Doc Request testing tool or my code
I am getting the same error message with their API v1
cURL request used (from their API docs)
curl -X POST "https://send.api.mailtrap.io/api/send" \
-H "Accept: application/json" \
-H "Api-Token: xxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"to":[{"email":"john_doe#example.com","name":"John Doe"}],"from":{"email":"sales#example.com","name":"Example Sales Team"},"subject":"Your Example Order Confirmation","html":"<p>Congratulations on your order no. <strong>1234</strong>.</p>"}'
Similar cURL request via PHP (same error message)
<?php
$post = [];
$post['to'] = 'test#test.com';
$post['from'] = ['name' => 'Test', 'email' => 'test#test.com'];
$post['subject'] = 'Test';
$post['html'] = '<h2>This is a test</h2><p>It works!</p>';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://send.api.mailtrap.io/api/send');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Api-Token: xxxxxxxxxxxxxxxxxxxxxxxxx']);
$result = curl_exec($ch);
print_r($result);
echo "\n";
I finally found the answer, here are my conclusions:
As of Today (Sep 2022), Mailtrap's Sending API cannot be used to send e-mails to your Mailtrap Sandbox (i.e. Fake Inbox). It can only be used to send real/production e-mails, to real users.
If your Mailtrap account is older than a year, you will most likely be missing the "Send API" section in your account and only see the "API" section. The only solution to address that was to create a new account.
If you still plan to use Mailtrap's Sending API (to send production e-mails), you will need to reach out to Support for some pre-configuration (This is not mentioned in the documentation) otherwise you will receive "Forbidden" from the API, without any additional details.
Does it mean we needs to write separate logic for dev/staging (using SMTP) and for prod (using API) in our apps? Sounds really strange.
I've looked into this and I have found the solution to your problem.
When looking at the send documentation, it states that you must also include an inbox id in your url and also use the sandbox url.
So, if you change your url from https://send.api.mailtrap.io/api/send to https://sandbox.api.mailtrap.io/api/send/1234567 then it should work - At least it did for me!
You can get the inbox id by going to the specific inbox in the webinterface and copy it from the url.

How can this curl command be converted to pycurl or python requests?

any hel pwill be highly appreciated. Just can't make this to work. I am basically trying to update my Grafana dashboard via a http request. managed to get it to work with curl but want to do this with python's requests or pycurl.
curl -X PUT https://<api token>#ks.hostedgraphite.com/api/v2/grafana/dashboards/<my_dashboard> --data-binary #dashboard.json
The command above works. Tried several ways, an example of a code snippet:
crl = pycurl.Curl()
crl.setopt(crl.URL,
'https://apitoken#ks.hostedgraphite.com/api/v2/grafana/dashboards/<my_dashborad>')
crl.setopt(crl.UPLOAD, 1)
file = open('dashboard.json')
crl.setopt(crl.READDATA, file)
crl.perform()
crl.close()
file.close()
print('Status: {}'.format(crl.getinfo(crl.RESPONSE_CODE)))
curl -X PUT https://api_token#ks.hostedgraphite.com/api/v2/grafana/dashboards/my_dashboard --data-binary #dashboard.json
translates to
import requests
data = open('dashboard.json', 'rb').read()
response = requests.put('https://api_token#ks.hostedgraphite.com/api/v2/grafana/dashboards/my_dashboard', data=data)
Just replace proper values for api_token and my_dashboard.
You can use https://curl.trillworks.com/ for converting curl commands to equivalent code using python requests.
ok, so my main issue was creating a http request via python requests.
Figured it out, I setthe auth param to auth=("graphite_api_token","") and it worked:
data = json.dumps(dashbord_dict)
headers = {"Accept": "application/json","Content-Type":"application/json"}
response =requests.put('https://ks.hostedgraphite.com/api/v2/grafana/dashboards/some_dashboard,auth=("graphite_api_token",""),data=data,headers=headers)
print(response.status_code)

how to send correct curl command to webserver

So I got the data that is being sent to a specific server. Now I want to do the same using curl from my local machine to play around with specific repsonses from the server and learn more about curl as well.
Here is part of my data
POST /auth HTTP/1.1
platform: android
X-Auth-Token: <censored>
Content-Type: application/json; charset=utf-8
Host: api.blabla.com
Accept-Encoding: gzip
And the data that is being sent:
{"blabla_token": "sdsadsad", "blahblah_id": "23213", "locale": "us"}
Now when I try cURL in my dos shell, I try
curl --insecure -X POST https://api.blabla.com/auth --data '{"blabla_token": "sdsadsad", "blahblah_id": "23213", "locale": "us"}'
The response I get from cURL is this:
{"code":401,"error":"blablaTokenRequired"}
Even though I specified the token. So there are two possible scenarios because the token is correct:
It has something to do with the SSL thing? (I use --insecure because I get an SSL error otherwise)
Something about my command is not correct but I can't figure out what.
Can someone kindly help me out? I am trying everything I can without success
I am not sure if I understand your application specific right, but probably one thing you need to take into account:
man curl says:
-d, --data <data>
(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. Compare to -F, --form.
-d, --data is the same as --data-ascii. --data-raw is almost the same but does not have a special interpreta‐
tion of the # character. To post data purely binary, you should instead use the --data-binary option. To URL-
encode the value of a form field you may use --data-urlencode.
As I can't see in your example the necessity of sending data as HTML form input, probably your application expects just a "raw" POST body and then you have to try this:
curl --insecure -X POST https://api.blabla.com/auth --data--binary '{"blabla_token": "sdsadsad", "blahblah_id": "23213", "locale": "us"}'
PS and for sure this is error is not about using --insecure which just asks curl to neglect ssl verification
you forgot the headers and enabling compressed encoding (gzip), however, i believe you can't force curl to only support gzip encoding using the curl command line alone, you will have to use libcurl, this will make the request say "Accept-Encoding: gzip,deflate" on most systems, using --compressed .. if that's not acceptable to you, rewrite it using libcurl (where you can force it to say only "gzip", if you wish, via CURLOPT_ENCODING )
curl -X POST https://api.blabla.com/auth --data '{"blabla_token": "sdsadsad", "blahblah_id": "23213", "locale": "us"}' --header 'platform: android' --header 'X-Auth-Token: <censored>' --header 'Content-Type: application/json; charset=utf-8' --header 'Host: api.blabla.com' --compressed
another gotcha: on some systems, there will be a default useragent header (like debian 6), while on some systems, curl comes without a default useragent (like debian 8).. you might want to use --user-agent '' too

How do I post data to an external endpoint from Apache Module?

I'm coding an Apache Module. In the same I'm able to read the request parameters and make some params by processing the request. Now I want to post this data to the external endpoint. How do I do that?
Say I have a data
char* data = "{clientid:2433211456}"; and I want to post it to a URL example.com/getPostedData in async mode, how do I do that?
NOTE : Currently I'm working with plan Apache libs and APXS tool. If I can have some modules on which I can Build the same, please do suggest.
I have solved this issue as follows :
I used curl to post the request.
Installed libcurl-devel
In the handler method :
char* postData="hello=hie";
CURL *curl;
curl = curl_easy_init();
ap_rprintf(r,"Intialized Curl!<br>");
if(curl) {
ap_rprintf(r,"Curl Request Posting Started!<br>");
curl_easy_setopt(curl, CURLOPT_URL,"http://google.com/search");
//curl_easy_setopt(curl, CURLOPT_POST,1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS,postData);
ap_rprintf(r,"%d",curl_easy_perform(curl));
curl_easy_cleanup(curl);
}
Compiled it as : apxs -i -a -c mod_example.c -lcurl
Done!!
For more reference on libcurl : http://curl.haxx.se/libcurl
Find my sample module code on github here.

Curl command to test the API

I need to test an API of following spec
URL: http://myapp.com/api/upload/
Method: POST
Parameters:
image: (binary data of image)
returns
a JSON Object
sample php implementation to test the api
<?php
$ch = curl_init();
$url = 'http://myapp.com/api/upload/';
$fields = array('image'=>file_get_contents('profile-pic.jpg'));
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_URL, $url);
$json = curl_exec($ch);
echo "\n".$json."\n";
?>
I use RESTClient and Poster extensions to test other api, I'm not sure how to send binary data for a parameter named image with those tools.
How do I test the above api using Curl command?
No luck with this one
curl -X POST --data-binary "image=#test.jpg" "http://myapp.com/api/upload/"
test.jpg is in current directory. I can't change the 3rd party API, to be able to test with other encoding formats.
curl -X POST --data-urlencode 'image#test.jpg' 'http://myapp.com/api/upload'
It’s image#, not image=#.
This is assuming that the image data is urlencoded before sending, which is what I figure the PHP code does.
CURLOPT_POSTFIELDS with a hash array in PHP corresponds to the command line -F option. Thus, it should be something similar to:
curl -F image=#profile-pic.jpg http://myapp.com/api/upload/
If that isn't the exact thing, add '--trace-ascii dump.txt' to get a full trace logged and check that out closely to see what's wrong.