Calling REST API with special characters in data parameters from Perl is failing - perl

From perl i'm trying to call a servicenow rest api to update some data attributes.
I'm using curl command to achieve this and for some reasons i can't use any of the perl modules available.
I'm able to achieve this successfully without any special characters in the value field of the json.
Following is the code used for formatting the cmd:
my $comments = "b'c";
my $cmd = `curl \"$url\" -i -s --insecure --user test:test --request PUT --header "Accept:application/json" --header "Content-Type:application/json" --data '{\"comments\":\"$comments\"}'`;
If the above value is "bc" i'm able to get the data, but if i give "b'c" the i'm getting following errors:
sh: -c: line 0: unexpected EOF while looking for matching `"'
sh: -c: line 1: syntax error: unexpected end of file
Even i tried the following code:
my $cmd = system "curl https://test.service-now.com/api/now/table/incident/code?sysparm_display_value=true -i -s --insecure --request PUT --header \"Accept:application/json\" --header \"Content-Type:application/json\" --data '{\"comments\":\"bc\"}' --user test:test";
If a string with single quote b'c is given I'm getting the same error.
Could somebody please tell me how to handle single quote inside double quoted string?

I can get this working with
my $comments = "b\"'\"c";
The string that gets passed to the shell is then
--data '{"comments":"b'"'"'c"}'
which is three separate tokens concatenated together:
'{"comments":"b' resolves to {"comments":"b
"'" resolves to '
'c"}' resolves to c"}
Also see String::ShellQuote, which is a godsend for problems like this.
use String::ShellQuote;
$comments = "b'c";
#cmd = ("curl", $URL, "-i", "-s", "--insecure", "--request",
"PUT", "--header", "Accept:applicatin/json", "--header",
"Content-Type:application/json",
"--data", qq[{"comments":$comments}], "--user", "test:test");
$cmd = shell_quote(#cmd);
print $cmd;
Gives you:
curl 'https://test.service-now.com/api/now/table/incident/code?sysparm_display_value=true'
-i -s --insecure --request PUT --header
Accept:application/json --header Content-Type:application/json
--data '{"comments":"b'\''c"}' --user test:test
which would also satisfy the shell's syntax checker.

Related

Unable to use curl with double quote using powershell (Hubspot API)

I use Hubspot API.
I try to craete contact info.
Type this code using powershell (5.1version and 7.2)
curl.exe --request POST --url "https://api.hubapi.com/crm/v3/objects/contacts?hapikey=$apiKey"
--header 'content-type: application/json' -d "{\"properties\": {\"email\":\"$email\",\"firstname\":\"$firstname\"}}"
but error
return {"status":"error","message":"Invalid input JSON on line 1, column 3: Unexpected character ('\\' (code 92)): was expecting double-quote to start field name","correlationId":"2086b3bc-abe5-4f90-a79c-213d45bb2a97"}
I try this code using single quote after -d.
and then create contact info.
curl.exe --request POST --url "https://api.hubapi.com/crm/v3/objects/contacts?hapikey=$apiKey" --header 'content-type: application/json' -d '{\"properties\": {\"email\":\"xxx#yyy.co.jp\",\"firstname\":\"k\"}}'
but I want to substitute variables. So I want to use double quote.
I solved by myself.
put double-quotes and backslash between variable.
ConvertTo-Json
setting 2. to curl.exe
like this
$contactBody = #{
'"properties"' = #{
'"firstname"' = "`"$firstname`""
'"email"' = "`"$email`""
}
}
$contactBodyJson = ConvertTo-Json $contactBody
curl.exe --request POST --url "https://api.hubapi.com/crm/v3/objects/contacts?hapikey=$apiKey" --header 'content-type: application/json' -d $contactBodyJson

Convert Powershell command to curl

I am trying make the following API calls with a curl command and run it on Linux:
https://octopus.com/blog/manually-push-build-information-to-octopus
This what I got:
curl -X POST https://YourServerUrl -H "X-Octopus-ApiKey"="API-XXXXXXXXXXXXXXXXXXXXXXXXXX" -H "Content-Type: application/json" -d "#jsonBody"
I am not sure how to convert this script to a json in curl
$jsonBody = #{
PackageId = "twerthi/xCertificatePermission"
Version = "1.0.0"
OctopusBuildInformation =
#{
BuildEnvironment = "Jenkins"
VcsCommitNumber = "2350881a389517288b31432d469c5c4199a1fba9"
VcsType = "Git"
VcsRoot = "https://github.com/twerthi/xCertificatePermission.git"
}
} | ConvertTo-Json -Depth 10
The curl command -d (--data) is the specified data in the POST request. So you should be able to just enter valid JSON data as part of the call. i.e. something like this:
curl -X POST https://YourServerUrl -H "X-Octopus-ApiKey"="API-XXX" -H "Content-Type: application/json" -d '{ "PackageId":"twerthi/xCertificatePermission", "Version":"1.0.0", "OctopusBuildInformation":{ "BuildEnvironment":"Jenkins", "VcsCommitNumber":"2350881a389517288b31432d469c5c4199a1fba9", "VcsType":"Git", "VcsRoot":"https://github.com/twerthi/xCertificatePermission.git"}}'
Note, if you are testing this in cmd/bash etc, you can split the command over multiple lines by using an escape character. Windows: ^ Linux/MacOS: \
Example in Windows:
curl -X POST https://YourServerUrl ^
-H "X-Octopus-ApiKey"="API-XXX" ^
etc....
Also, assuming that's valid PS, you can just run it and check the result in $jsonBody to see how its formatted.
Assuming you want to call the external curl utility from PowerShell (note that on Windows, in Windows PowerShell, you'll have to call it as curl.exe):
curl -X POST https://YourServerUrl `
-H 'X-Octopus-ApiKey: API-XXXXXXXXXXXXXXXXXXXXXXXXXX' `
-H 'Content-Type: application/json' `
-d ($jsonBody -replace '([\\]*)"', '$1$1\"')
Note the unfortunate need for a -replace operation on the $jsonBody variable containing your JSON string, which - as of PowerShell 7.1 - is needed to work around a long-standing bug, discussed in this answer.

MarkLogic ingest JSON from external API

I am using Marklogic 9 and try to ingest data from external source into MarkLogic. I made an REST API on port 8031. When I try to execute the following curl command:
curl --anyauth --user admin:admin -i -X POST -d https://services7.arcgis.com/21GdwfcLrnTpiju8/arcgis/rest/services/Geluidsbelasting/FeatureServer/0/query?where=1%3D1&outFields=*&outSR=4326&f=json
-H "Content-type: application/json" -H "Accept: application/json" \
'http://localhost:8031
After executing this statement I receive the error:
Curl: URL is not specified
Can you please help me out!
Many thanks
Erik
Your -d parameter has special characters that are not escaped. Try putting quotes around your -d url. It will prevent your command from getting truncated and misinterpreted at & signs..
HTH!

curl command line POST password

I have the following curl command which works perfectly fine:
curl --silent --location -cookie "$COOKIE" --cookie-jar "$COOKIE" \
--form 'username=xxx' --form 'password=yyy' 'http://example.com'
It logs into site http://example.com posting a form with variable names username and password.
Problem is: I do not want to pass the password in clear.
I have also tried to save the password in a file called passwd in the working directory (chmod 600 passwd) and used the following curl command (this is why I used --form instead of --data, which would have been worked fine with the password in clear), however, it does not work:
curl --silent --location -cookie "$COOKIE" --cookie-jar "$COOKIE" \
--form 'username=xxx' --form 'password=<passwd' 'http://example.com'
Any suggestion about how to solve this?
Regards,
Stefano
Hans Z. answer to use environmental variable is correct in my opinion. Though I might just add that in bash you could use read command, which would prompt for password and not make it visible in history.
So the usage would look like this
$ read -s PASSWD # -s is there so the characters you type don't show up
$ curl --silent --location -cookie "$COOKIE" --cookie-jar "$COOKIE" \
--form 'username=xxx' --form "password=${PASSWD}" 'http://example.com'
UPDATE:
Another solution found in the comments is to use curl's --data-urlencode name#filename argument.
Quoting the manpage:
name#filename
This will make curl load data from the given file (including any newlines), URL-encode that data and pass it on in the POST.
And the final command looked like
$ curl --silent --location -cookie "$COOKIE" --cookie-jar "$COOKIE" \
--data 'username=xxx' --data-urlencode "password#passwd" 'http://example.com'
Set the password in an environment variable, e.g. export PASSWD=secret and use it in --form "password=${PASSWD}".
Passing secrets in command line is insecure as they are available in process list.
You should use the --data-urlencode name#filename approach
This will make curl load data from the given file
(including any newlines), URL-encode that data and
pass it on in the POST.
or -K, --config <file>
Specify a text file to read curl arguments from. The
command line arguments found in the text file will be used
as if they were provided on the command line.
See also this anwser

Curl thowing error while trying to query JIRA with strings in field filter

I need some help with my perl script.
I am new to perl and using curl and despite a lot of searching/ trial and error I am still stumped.
I am trying to use CURL to retrieve a set of jira issues based on the provided JQL.
Unfortunately I am having issues with spaces when I search fields like summary:
my $jql = JiraUrl.'search?jql=summary~"Some%20Silly%20Issue"';
When I curl this...
my $jsonResponse = `curl -D- -u $user:$password -X GET -H "Content-Type: application/json" $jql`;
I get an error ..
{"errorMessages":["Error in the JQL Query: Expecting either \'OR\' or \'AND\' but got \'Silly\'. (line 1, character 77)"],"errors":{}}';
Basicly when I escape the " " with %20 it ignores the "'s
Any help for how to get around this?
It looks like it's a shell escaping issue. The quotes are being interpreted by the shell. Try this:
my $jsonResponse = `curl -D- -u $user:$password -X GET -H "Content-Type: application/json" '$jql'`;