How to submit arrays without keys via php curl? - php

I need to submit various fields via curl request. Some fields are simple types like strings or integers, some are files and some are arrays.
The target server is not able to accept array fields in case of submitting with keys in field name. They should be submitted with fieldnames like fieldname[] and NOT via fieldname[0].
From the docs i got this working example:
curl -H "Authorization: __TOKEN__" \
-H "Accept: application/json" \
-H "Extended-errors: true" -X POST \
-F 'foo[field_a]=Dev' \
-F 'foo[field_b]=https://example.org' \
-F 'foo[field_c][]=bar1' \
-F 'foo[field_c][]=bar2' \
-F 'foo[field_c][]=bar3' \
-F 'foo[field_d]=#/path/to/file.jpg' -g -v \
"https://api.example.com/endpoint"
I need to do this via PHP using the curl extension and tried this:
$url = 'https://api.example.com/endpoint';
$fields = [
'foo[field_a]' => 'Dev',
'foo[field_b]' => 'https://example.org',
'foo[field_c][0]' => 'bar1',
'foo[field_c][1]' => 'bar2',
'foo[field_c][2]' => 'bar3',
'foo[field_d]' => new CURLFile('/path/to/file.jpg'),
];
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields);
//execute post
$result = curl_exec($ch);
As you can see i had do use indexes for field_c because i cannot define foo[field_c][] twice in $fields array. In case of having just one item in array it works with key foo[field_c][]!
However, foo[field_c][0] does not work for the target server. I don't know if this is a bug or not but it is the case. If i do it this way from command line it fails, too.
If I use no indexes it works. So I need to be able to send arrays like this fieldname[] via php.
I also tried to define foo as full array and set the postfields via http_build_query($fields). But with the same result because http_build_query creates fieldnames with indexes, too.
Is there some way to send array fields without an index via php curl?
Is this remote hosts behaviour a bug? I.e. it is somewhere specified in specs that the server should accept arrays with keys?

Related

Curl request not working using php script

I have curl using voxbone API action method pass "did_dropdown" parameter value to get country wise dids. But another thing I am passing action method "didlist_type_city" parameter value not any response with pass country.
Note : Get url is working on terminal command line but postman api not any response get
curl -u xxxxx:xxxxx -H "Content-type: application/json" -H "Accept: application/json" "https://sandbox.voxbone.com/ws-voxbone/services/rest/inventory/did?didIds='xxxxxx'&pageNumber=0&pageSize=1&countryCodeA3=IND"

How can I send a json data along with a file in a curl request to handle by Flask?

Problem:
I want to send a file with -F option and along with a json data with -d to the flask route.But only either i can implement.
Code I tried.
curl -X POST -H "Content-Type: application/json" -d '{"username":"xyz","password":"xyz"}' http://192.168.150.113/test
Flask Code:
#app.route('/test',methods = ['GET', 'POST'])
def test():
if request.method == 'POST':
data = request.data
data = json.loads(data)
return 'success'
With only File :
curl -X POST -F file=#sample.txt http://192.168.150.113/test
#app.route('/process' , methods = ['GET', 'POST'])
def process():
if request.method == 'POST':
f = request.files['file']
if f:
try:
filename = secure_filename(f.filename)
f.save( os.path.join(app.config['UPLOAD_FOLDER'], filename ))
return 'success'
But without sending seperate request I want to combine these two POST request and handle using flask..
Is there any way I can do this?
Use the -F option to send data with multipart/form-data
curl -X POST -H "Content-Type: multipart/form-data" -F "file=#sample.txt" -F "username=xyz" -F "password=xyz" http://localhost:5000/test
You cannot send file with json together as they have different Content-Type. Alternatively, you can stringify your json and send them with multipart/form-data. For example, you can send a form like the following:
curl -X POST -H "Content-Type: multipart/form-data" -F "file=#sample.txt" -F "json_data='{\"username\":\"xyz\",\"password\":\"xyz\"}'" http://localhost:5000/test
And in python, you can get this json by request.form.get("json_data"). It is more robust than passing key-value pairs through plain multipart/form-data as it support much more complicated structure.

Post json data stored in variable using curl

Sending POST request data stored in a variable using curl, sends $variable instead json data.
P=`/usr/bin/sudo /usr/bin/curl -X POST -H "Content-Type:application/json" --data-urlencode $data http://127.0.0.1/abc.php`
Trying to send POST request to php, but it receives $data instead json data{"abc":"11","xyz":"20"}.
Had try with '$data', "$data", \'$data\' and \"$data\", where $data = {"abc":"11","xyz":"20"}
Please give an example that works. Thanks in advance.
P=`/usr/bin/sudo /usr/bin/curl -X POST -H "Content-Type:application/json" -d "$O" http://127.0.0.1/abc.php` solves issue.
If you add single quote it won't expand variable, so it requires to add double quote.
I suggest all time reload page or script, as I have seen if you not reload, it work with your last change instead new one.

How to urlencode a empty array(not null but empty) in php, to pass to CURLOPT_POSTFIELDS of a curl request?

I am creating Fb messenger bot in php and using curl to interact with fb server. now for sending a file fb wants me to send request in this format
` curl \
-F recipient='{"id":"USER_ID"}' \
-F message='{"attachment":{"type":"image", "payload":{}}}' \
-F filedata=#/tmp/shirt.png;type=image/png \
"https://graph.facebook.com/v2.6/me/messages?access_token=PAGE_ACCESS_TOKEN" `
Here you can see payload is an empty array.
What I am doing is
$res['message'] = [
'attachment' => [
'type' => 'image',
'payload' => [
]
]
]; `
After this I am using curl_setopt like this
curl_setopt($process, CURLOPT_POST, 1);
curl_setopt($process, CURLOPT_BINARYTRANSFER , true);
curl_setopt($process,CURLOPT_POSTFIELDS, http_build_query($data));
But this doesn't work and I am getting
{"error":{"message":"(#100) The parameter message[attachment] [payload] is required","type":"OAuthException","code":100,"fbtrace_id":"EaQ66DTssrV"}}
After some debugging I reached at the conclusion that since my attachment array is empty http_build_query does not take it into account.
see first comment here
So my question is how to urlencode a empty array in php.
what I have tried till now
tried using array() and ''(single quotes) by assigning it to payload(here payload was included but was empty and fb seerver returned same error)
I can send other type of message successfully that does not include empty array.
curl command given is correct as I executed it from my shell using ssh access.
content type is multipart/form data.
I am sending data and file in a single request is it fine?
tried passing data without encoding - fb error recipient is empty
tried passing array directly to POSTFIELDS but got {"error":{"message":"(#100) param recipient must be non-empty.","type":"OAuthException","code":100,"fbtrace_id":"BQ00BtZZmPF"}}
If there is a better way to execute this curl command in php please tell me. Thanks

Posting nested params with curl -F flag

I’m trying to post an image and a few nested parameters to an api using django rest framework. I’m trying to set up a curl with -F flags as discussed here with nested params as discussed here:
curl -X POST -S -H 'Accept: application/json' -F "customer[name]=foo&customer[email]=foo#bar.com&customer[zipcode]=1076AL&customer[city]=Amsterdam&customer[address]=foobar" -F "photo=#/Users/vincentvanleeuwen/Desktop/tmp/accord.jpg;type=image/jpg" http://localhost:8000/api/orders/
But I get the following response:
{"customer":{"city":["This field is required."],"email":["This field is required."],"zipcode":["This field is required."],"name":["This field is required."]}}
There seems to be something wrong with my nesting under the -F flag, as the nested variables work if I post it like this:
curl -X POST -S -H "Content-Type: application/json" -d '{"customer":{"name":"Adriaan","email":"adriaan#adriaan.com","zipcode":"1901ZP","address":"caravan","city":"Verweggistan"}}' http://localhost:8000/api/orders/
Any ideas what I’m doing wrong? Any help would be much appreciated!
Try separate -F flags for each parameter? From the curl manual:
Emulate a fill-in form with -F. Let's say you fill in three fields
in a form. One field is a file name which to post, one field is your
name and one field is a file description. We want to post the file
we have written named "cooltext.txt". To let curl do the posting of
this data instead of your favourite browser, you have to read the
HTML source of the form page and find the names of the input fields.
In our example, the input field names are 'file', 'yourname' and
'filedescription'.
curl -F "file=#cooltext.txt" -F "yourname=Daniel" \
-F "filedescription=Cool text file with cool text inside" \
http://www.post.com/postit.cgi

Categories