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

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.

Related

golang passing data payload from HTTP client

I have an HTTPS endpoint that works fine with a cURL command like this:
curl -k -u xyz:pqr \
--data "grant_type=client_credentials" \
https://my-url
Now I am trying to use golang to call the same API endpoint like this:
data := url.Values{}
data.Set("grant_type", "client_credentials")
req, err := http.NewRequestWithContext(
ctx,
"POST",
"https://my-url",
strings.NewReader(data.Encode())
)
It fails with the error body:
{
"error_description":"grant_type is required",
"error":"invalid_request"
}
I am already passing grant_type as the last argument to the http.NewRequestWithContext() function.
What am I missing?
You are not translating the curl correctly. This tool might be helpful: https://mholt.github.io/curl-to-go/
Essentially you need to add user auth.
req.SetBasicAuth("xyz", "pqr")
// Might help to set the `Content-Type` too
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
-k on curl seems to be reading some curl arguments from a file too. You are going to want to make sure you translate those over as well. I cannot see what they are from your example.

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)

NiFi- how to http post a PDF document

I wanted to use NiFi's posthttp/invokeHttp processor to post a PDF to an API.
But considering the following cURL request to replicate in NiFi:
curl -X POST "http://ipaddress:port/api/" -H "accept: application/json" -H
"Content-Type: multipart/form-data" -F "pdf_file=#sample.pdf;
type=application/pdf"
Which property takes the -F information in nifi attributes?
Configuration for invokehttp right now:
error:
"400 Bad Request: The browser (or proxy) sent a request that this server could not understand."
Configration for posthttp right now:
error:
server logs: readv() failed (104: Connection reset by peer) while reading upstream
In older version of nifi you will have to use your own script to build a multipart request and then use invoke to create post request. You can refer to this post for a ExecuteGroovyScript example.
https://stackoverflow.com/a/57204862
Since Nifi 1.12 you can directly use invokeHTTP by setting content-type
https://stackoverflow.com/a/69284300
When you use PostHttp/InvokeHttp you wouldn't be referencing an external file, you would be sending the content of the flow file. So you would first need to bring sample.pdf into NiFi by using GetFile or ListFile/FetchFile and then flow file coming out of those processors represents the PDF, and you would route that flow file to InvokeHttp which would POST the content of the flow file (the pdf).

Is there a way to add additional configurable settings in OpsCenter 6.0.2 Lifecycle Manager config profiles?

I would really like to add the following settings to our spark-defaults.conf using OpsCenter 6.0.2 in order to avoid configuration drift. Is there a way to add these config items to the config profile template?
spark.cores.max 4
spark.driver.memory 2g
spark.executor.memory 4g
spark.python.worker.memory 2g
NOTE: As Mike Lococo has pointed out in the comments for this answer -- this answer may work to update the config profile values but will not result in those values being written to spark-defaults.conf.
The following is not a solution!
You can; you have to update the config profile via the LCM Config Profile API (https://docs.datastax.com/en/opscenter/6.0/api/docs/lcm_config_profile.html#lcm-config-profile).
First, identify the config profile that needs updating:
$ curl http://localhost:8888/api/v1/lcm/config_profiles
Get the href for the specific config profile that needs updating, request it, and save the response body to a file:
$ curl http://localhost:8888/api/v1/lcm/config_profiles/026fe8e3-0bb8-49c1-9888-8187b1624375 > profile.json
Now, in the profile.json file you just saved to, you add or edit the key at json > spark-defaults-conf to include the following keys:
"spark-defaults-conf": {
"spark-cores-max": 4,
"spark-python-worker-memory": "2g",
"spark-ssl-enabled": false,
"spark-drivers-memory": "2g",
"spark-executor-memory": "4g"
}
Save the updated profile.json. Finally, execute an HTTP PUT to the same config profile URL, using the edited file as the request data:
$ curl -X PUT http://localhost:8888/api/v1/lcm/config_profiles/026fe8e3-0bb8-49c1-9888-8187b1624375 -d #profile.json

cURL in PHP to extract json

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.