Libcurl GET POST parameters

libcurl
Clarion6.3
Example HTTPWebServices.app

Url field : Send:Url
Parameters field : Send:PostParams
CustomRequest field : Send:CustomRequest

res = curl.SendRequest(Send:Url, Send:PostParams, respBuffer)

I need to test API on GEt and POST requests:

1 GET . curl --location --request GET ‘https://myspotlight.app/api/int/user-info?apikey=SL12345&P_BARKOD=00750000000011
–data-raw ‘’

CALL : https://server.app/api/int/user-info?apikey=SL12345&P_BARKOD=00750000000011

When I put above call in Send:Url field (Send:CustomRequest = GET) , I get right response from server .

When tried to separate above string :
Send:Url : https://server.app/api/int/user-info
Send:PostParams : apikey=SL12345&P_BARKOD=00750000000011 ,

I get error , apikey field is mandatory

2 POST . curl --location --request POST ‘https://server.app/api/int/insert-transaction-v2
–data-raw ‘{
“apikey”: “SL-12345”,
“p_id”: “105”,
“p_orgjed”: “10”,
“p_pan”: “00750000000011”,
“p_user_id”: “100”,
“p_iznos_racuna”: 50,
“p_iznos_bez_ak”: 0,
“p_iznos_placen_bp”: 1,
“p_iznos_placen_pp”: 5,
“p_komentar”: “”,
“stavke”: [
{
“rbr”: 1,
“artikal”: “14”,
“kolicina”: 1,
“popust”: 0,
“iznosMP”: 50
}
],
“vauceri”: { “1”:{“kod”:“000001002005978451”} }
}’

I create file (datafile ) from content of --data-raw ’ { … } ’ , and tried with command :

res = curl.SendFile(Send:Url, clip(datafile), Send:PostParams, Send:Filename)
where
Send:Url = https://server.app/api/int/insert-transaction-v2
Send:Filename=’’
Send:PostParams= POST

But, I get no response at all
I tested curl command on REQBIN , server responded.

Any help ?

  1. GET request ignores POST parameters (Send:PostParams).
  2. Why don’t you send raw data?
    Send:PostParams =   '{{'                                                 |
    & '"apikey": "SL-12345",'                              |
    & '"p_id": "105",'                                     |
    & '"p_orgjed": "10",'                                  |
    & '"p_pan": "00750000000011",'                         |
    & '"p_user_id": "100",'                                |
    & '"p_iznos_racuna": 50,'                              |
    & '"p_iznos_bez_ak": 0,'                               |
    & '"p_iznos_placen_bp": 1,'                            |
    & '"p_iznos_placen_pp": 5,'                            |
    & '"p_komentar": "",'                                  |
    & '"stavke": ['                                        |
    & '{{'                                                 |
    & '"rbr": 1,'                                          |
    & '"artikal": "14",'                                   |
    & '"kolicina": 1,'                                     |
    & '"popust": 0,'                                       |
    & '"iznosMP": 50'                                      |
    & '}'                                                  |
    & '],'                                                 |
    & '"vauceri": {{ "1":{{"kod":"000001002005978451"} }'  |
    & '}'

    curl.SetCustomRequest('POST')
    curl.SendRequest(Send:Url, Send:PostParams, respBuffer)

And always inspect DebugView log, it contains many useful info and helps to find what’s going wrong.

Thanks,

it works, same response from API , as native curl call.

What is a size of Send:PostParams . I know that it has to be used as params , but is there any size limit of Send:PostParams (raw data) ?
In what cases we use curl.SendFile ?
In my case I tried
res = curl.SendFile(Send:Url, datafile, Send:PostParams, Send:Filename)
If I create datafile respecting your corrections in brackets and quotation marks , could I
use it. What is in that case Send:PostParams ?

Thanks again

Look at SendFile declaration, it doesn’t accept PostParams argument, but it expects contentType (but it can be a blank string). Actually SendFile is curl’s “–data-binary” equivalent.

AFAIK there are no limits for postparams data.

How looks libcurl call for twilio whatsapp project:

https://api.twilio.com/2010-04-01/Accounts/AC36a490581e1a6b00f075ac43c65f8728/Messages.json’ -X POST \

–data-urlencode ‘To=whatsapp:tonumber’ \

–data-urlencode ‘From=whatsapp:fromnumber’ \

–data-urlencode ‘Body=Your appointment is coming up on July 21 at 3PM’ \

-u AC36a490581e1a6b00f075ac43c65f8728:[AuthToken]

Thanks

You must url encode To, From and Body, and combine them to post parameters, something like this:

postparams = printf('To=%U&From=%U&Body=%U', var:to, var:from, var:body)
curl.Init()
curl.SetUserPwd(sid, token)
ret = curl.SendRequest(url, postparams, respfile)

I tried to put libcurl in multidll app for sending mail .
Exported procedures from 6.3 example SendMail imported in dll .
Compiling passed , but on start main exe I got an error
image

Something missed-
What has to be in datadll, dlls and in exe ?

Looks like libcurl.dll is outdated.

Response file was same like in POSTMAN,
{“errors”:{“apikey”:[“Mandatory field!”],“p_orgjed”:[“Mandatory field!”],“p_user_id”:[“Mandatory field!”]}} .
Point is that I imported CURL in POSTMAN like raw text, didn’t change body from x-www-form-urlencoded to raw JSON and didn’t pasted data in JSON . When I did that response changed to
{
“transakcija_status”: “OK”,
“transakcija_poruka”: " Ovim racunom iznos bonitetnih poena koji ste ostvarili je:0Trenutno stanje dobroimetja za koriščenje je: 9,338.93",
“transakcija_stanje_bp”: 9338,
“transakcija_stanje_pp”: 4,
“transakcija_bp_dobijeno”: 0,
“transakcija_trans”: “81184”,
“vauceri”: {
“1”: {
“kod”: “000001002005978451”,
“status”: “OK”
}
},
“msg”: “OK”
}
.That is right response .
My libcurl call is;
POST : https://myspotlight.app/api/int/insert-transaction-v2
if Send:CustomRequest=‘POST’
Send:PostParams =’{{’ |
& ‘"apikey”: "SL-0a9e160bfec9-f69a94c16fa7-7634627146c0”,’ |
& ‘"p_id”: "105”,’ |
& ‘"p_orgjed”: "10”,’ |
& ‘"p_pan”: "00750000000011”,’ |
& ‘"p_user_id”: "100”,’ |
& ‘"p_iznos_racuna”: 50,’ |
& ‘"p_iznos_bez_ak”: 0,’ |
& ‘"p_iznos_placen_bp”: 1,’ |
& ‘"p_iznos_placen_pp”: 5,’ |
& ‘"p_komentar”: "”,’ |
& ‘"stavke”: [’ |
& ‘{{’ |
& ‘"rbr”: 1,’ |
& ‘"artikal”: "14”,’ |
& ‘"kolicina”: 1,’ |
& ‘"popust”: 0,’ |
& ‘"iznosMP”: 50’ |
& ‘}’ |
& ‘],’ |
& ’ " vauceri”: {{ "1”:{{"kod”:"000001002005978451”} }’ |
& ‘}’
! message(Send:PostParams,2)
end
What I need to change?

You haven’t provided your libcurl calls, so I have no idea what do you need to change.
If you have working curl script, call it with -v option (or with --verbose) to get detailed output log, and compare it with debugview log produced by libcurl from your app.

“Original” CURL:

curl --location --request POST ‘https://myspotlight.app/api/int/insert-transaction-v2
–data-raw ‘{
“apikey”: “SL-0a9e160bfec9-f69a94c16fa7-7634627146c0”,
“p_id”: “105”,
“p_orgjed”: “10”,
“p_pan”: “00750000000011”,
“p_user_id”: “100”,
“p_iznos_racuna”: 50,
“p_iznos_bez_ak”: 0,
“p_iznos_placen_bp”: 1,
“p_iznos_placen_pp”: 5,
“p_komentar”: “”,
“stavke”: [
{
“rbr”: 1,
“artikal”: “14”,
“kolicina”: 1,
“popust”: 0,
“iznosMP”: 50
}
],
“vauceri”: { “1”:{“kod”:“000001002005978451”} }
}’


Libcurl from HTTPWebServices.app (C6.3)
Send:CustomRequest=‘POST’
SSLInfo:bUseSSL= true

SendRequest ROUTINE
DATA
curl TCurlHttpClass
res CURLcode
qIndex LONG, AUTO
respBuffer &IDynStr

CODE
respBuffer &= NewDynStr()
curl.Init()
curl.FreeHttpHeaders()
IF RECORDS(HttpHeaders)
LOOP qIndex = 1 TO RECORDS(HttpHeaders)
GET(HttpHeaders, qIndex)
curl.AddHttpHeader(HttpHeaders.HttpHeader)
IF res <> CURLE_OK
MESSAGE('AddHttpHeader failed: '& curl.StrError(res), ‘libcurl’, ICON:Exclamation)
END
END
res = curl.SetHttpHeaders()
IF res <> CURLE_OK
MESSAGE('SetHttpHeaders failed: '& curl.StrError(res), ‘libcurl’, ICON:Exclamation)
END
END

IF bGetServerResponse
    res = curl.SetHttpGET(TRUE)
    IF res <> CURLE_OK
        MESSAGE('SetHttpGET failed: '& curl.StrError(res), 'libcurl', ICON:Exclamation)
    END
END

IF Send:CustomRequest
    res = CURL.SetCustomRequest(Send:CustomRequest)
    IF res <> CURLE_OK
        MESSAGE('SetCustomRequest failed: '& curl.StrError(res), 'libcurl', ICON:Exclamation)
    END
END

res = curl.SetUserPwd(Send:User, Send:Pwd)
IF res <> CURLE_OK
    MESSAGE('SetUserPwd failed: '& curl.StrError(res), 'libcurl', ICON:Exclamation)
END

IF SSLInfo:bUseSSL
    res = curl.SetSSLVerifyHost(SSLInfo:bVerifyHost)
    IF res <> CURLE_OK
        MESSAGE('SetSSLVerifyHost failed: '& curl.StrError(res), 'libcurl', ICON:Exclamation)
    END
    res = curl.SetSSLVerifyPeer(SSLInfo:bVerifyPeer)
    IF res <> CURLE_OK
        MESSAGE('SetSSLVerifyPeer failed: '& curl.StrError(res), 'libcurl', ICON:Exclamation)
    END
    res = curl.SetSSLVersion(SSLInfo:Version)
    IF res <> CURLE_OK
        MESSAGE('SetSSLVersion failed: '& curl.StrError(res), 'libcurl', ICON:Exclamation)
    END
    IF SSLInfo:Certificate
        res = curl.SetCAInfo(SSLInfo:Certificate)
        IF res <> CURLE_OK
            MESSAGE('SetCAInfo failed: '& curl.StrError(res), 'libcurl', ICON:Exclamation)
        END
    END
END
if  Send:CustomRequest='POST'
Send:PostParams ='{{' |
& '"apikey”: "SL-0a9e160bfec9-f69a94c16fa7-7634627146c0”,' |
& '"p_id”: "105”,' |
& '"p_orgjed”: "10”,' |
& '"p_pan”: "00750000000011”,' |
& '"p_user_id”: "100”,' |
& '"p_iznos_racuna”: 50,' |
& '"p_iznos_bez_ak”: 0,' |
& '"p_iznos_placen_bp”: 1,' |
& '"p_iznos_placen_pp”: 5,' |
& '"p_komentar”: "”,' |
& '"stavke”: [' |
& '{{' |
& '"rbr”: 1,' |
& '"artikal”: "14”,' |
& '"kolicina”: 1,' |
& '"popust”: 0,' |
& '"iznosMP”: 50' |
& '}' |
& '],' |
& ' " vauceri”: {{ "1”:{{"kod”:"000001002005978451”} }' |
& '}'
!message(Send:PostParams,,,,,2)
end
Send:Url='https://myspotlight.app/api/int/insert-transaction-v2'

IF bSaveServerResponseToFile
    res = curl.SendRequest(Send:Url, Send:PostParams, Send:Filename)
ELSE
    res = curl.SendRequest(Send:Url, Send:PostParams, respBuffer)
END

IF res = CURLE_OK
    IF bSaveServerResponseToFile
        ?txtHttpResponse{PROP:Text} = 'Response saved to file: '&CLIP(Send:Filename)
        DISPLAY(?txtHttpResponse)
        SELECT(?txtHttpResponse)
    ELSE
        ?txtHttpResponse{PROP:Text} = CLIP(respBuffer.Str())
        DISPLAY(?txtHttpResponse)
        SELECT(?txtHttpResponse)
    END
ELSIF res = -1
    MESSAGE('Cannot open local file', 'libcurl', ICON:Exclamation)
ELSE
    SETCLIPBOARD('SendRequest failed: '& curl.StrError(res))
    MESSAGE('SendRequest failed: '& curl.StrError(res), 'libcurl', ICON:Exclamation)
END
DisposeDynStr(respBuffer)

When I say “working curl script” I mean working curl script, the script you provided will not work in DOS command prompt, because it is bad formatted. Perhaps it works on Linux.

If we believe that the script is theoretically correct, then you just need 4 lines on Clarion side:

curl.Init()
curl.SetCustomRequest(‘POST’)
curl.FollowLocation(TRUE)
res = curl.SendRequest(Send:Url, Send:PostParams, respBuffer)

Here is a original link to documentation


Address and JSON from data-raw content succesfully passed execution in POSTMAN and https://reqbin.com/.
I guess that I missing some banal things . Problem is that I don’t have libcurl example in FAQ to compare .
Thanks

Have no idea what could be wrong with the code I’ve provided (have you ever tried it?). See debugview log to find any error messages. Also you can add these 2 lines to avoid SSL verification:

  curl.SetSSLVerifyPeer(FALSE)  !curl --insecure
  curl.SetSSLVerifyHost(FALSE)  !curl --insecure

Here is a dbgview file of unsuccessful tries to execute POST CURL statement .
I will be very pleased if there is some working example with CURL POST --data-raw combination .
json.zip (2.5 KB)

As you can see in the LIBCURL log, you (implicitly) send "content-type: application/x-www-form-urlencoded " in the request header. try sending “content-type: text/plain” or “content-type: application/json”:

  curl.AddHttpHeader('Content-Type: text/plain')     
  curl.SetHttpHeaders()

I found out what is it .
On JSON formatter validator every line of JSON was problem .
I didn’t change closing double quatation marks , it stayed " apikey ” (as you see they are not the same) instead of “apikey”. Sorry for wasted time .

Hi @edo1403 , have you encountered scrambled local characters when retreving the JSON response from a server? Something like this:

For instance the response.txt file is created ok, and all the local characters are displayed correct. But when I try to put the json response into a variable to be able to proceed it and after that parse it, it shows up incorrect. Is there an UTF - 8 setting to be added, something like that?

Also I’ve used the &IDynStr interface, in example:
jsonresponse &= NewDynStr()
res = curl.SendRequest(url, PostParams, jsonresponse)
MESSAGE(‘Success, see file ‘& CLIP(jsonresponse.Str())&’ for details’, ‘Post test’, ICON:Asterisk)
MESSAGE(jsonresponse.Str())
DisposeDynStr(jsonresponse)

Thanks

Use cJSON to parse json response and do utf-8 decoding:

jParser        cJSONFactory
jResponse      &cJSON
  CODE
  jResponse  &= jParser.Parse(jsonresponse, CP_ACP)  !- jsonresponse is an IDynStr instance

Hi @Mike_Duglas ,

I realized that I forgot to add the second parameter in the Parse() function, the CP_APC. Now it works great. Thanks for the help.