Linux cURL XML file POST - how to check for error/success? - linux

I am using cURL to post a XML file on Linux as follows:
curl -X POST --header "Content-Type: text/xml" -d #test.xml "https://www.example.com"
How can I check the status of the cURL command to see if the file was posted or not?
Thanks for any help.

I'm not sure if I got you but you can basically check the return value of the curl command. The return value of the last command is stored in the variable $?.
Example:
curl -X POST --header "Content-Type: text/xml" -d #test.xml "https://www.example.com"
ret=$? # store return value for later usage in the error message
if [ $ret != 0 ] ; then
echo "POST failed with exit code $ret"
fi
This list of possible error codes can be found at the bottom of the man page. They are very helpful for debugging.

You can get the response status of your operation using -w %{http_code}
curl -s -o out.txt -w %{http_code} http://www.example.com/
In this example -s means silent mode, and -o out.txt means to save the response(usually html) into a file.
For this above command, you'l have output 200 when its success.

Related

Can you curl files from GitLab?

Is it possible to download a file from GitLab using the API? I am using CentOS 6 commandline. The documentation for the API says "Get file from repository" but it is only to get the metadata and not the file itself. The example they give is:
curl --request GET --header 'PRIVATE-TOKEN: <your_access_token>' 'https://gitlab.example.com/api/v4/projects/13083/repository/files/test%2Epy/raw?ref=master'
If I use the raw option, it gives me the contents of the file, but it saves the name with as test%2Epy/raw?ref=master
How do I get it to save as test.py?
Append > test.py to curl as below:
curl --request GET --header 'PRIVATE-TOKEN: ' 'https://gitlab.example.com/api/v4/projects/13083/repository/files/test%2Epy/raw?ref=master' > test.py
It's also possible to use the group and project name instead of the project-id:
response=$(curl "$GITLAB_URL/api/v4/projects/<group>%2F<project>/repository/files/<folder>%2Ftest%2E.py/raw?ref=master" \
--silent \
-o "test.py" \
--header "PRIVATE-TOKEN: $GITLAB_TOKEN")
if [[ $response == 4* ]] || [[ $response == 5* ]]; then
echo ERROR - Http status: "$response"
exit 1
fi
It's important to URL encode the group + project path and the file path as well.

Curl command doesn't work in bash script

I am trying to upload a JSON file into my noSQL database using a bash script, but it doesn't work and I don't understand why.
This is the script :
test='{"evaluation": "none"}'
test="'$test'"
command="curl -XPUT localhost:9200/test/evaluation/$i -d $test"
echo "$command"
$command
This is the error :
curl -XPUT localhost:9200/test/evaluation/0 -d '{"evaluation": "none"}'
{"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}curl: (3) [globbing] unmatched close brace/bracket in column 7
When I do the command given in my command line it works fine though.
What is the error here ? Thank you
Don't store a command in a variable; if you absolutely must have something usable with logging, put the arguments in an array.
test='{"evaluation": "none"}'
args=( -XPUT localhost9200/test/evaluation/"$i" -d "$test" )
echo "curl ${args[*]}"
curl "${args[#]}"

expanding shell variable in curl POST?

I use the following line to create database:
curl -X POST 'http://10.1.1.1:8086/db?u=root&p=root' -d '{name: test1}
if i try to do it from shell script:
ip=10.1.1.1
curl -X POST 'http://$ip:8086/db?u=root&p=root' -d '{name: test1}'
i have a problem with shell variable substitution within single quotas, if i try to use them within double quotas:
curl -X POST "http://$ip:8086/db?u=root&p=root" -d '{name: test1}'
variable is expanded to the right value, printing in terminal
curl -X POST "http://10.1.21.1:8086/db?u=root&p=root" -d '{name: test1}': **No such file or directory**
What would be the right solution to this problem?
Try this:
ip=10.1.1.1
curl -X POST 'http://'"$ip"':8086/db?u=root&p=root' -d '{name: test1}'

Perl/ curl How to get Status Code and Response Body

I am trying to write a simple perl script that calls and API and if the status code is 2xx the do something with the response. While if it is 4xx or 5xx then do something else.
The issue I am encountering is I am able to either get the response code (using a custom write-out formatter and pass the output somewhere else) or I can get the whole response and the headers.
my $curlResponseCode = `curl -s -o /dev/null -w "%{http_code}" ....`;
Will give me the status code only.
my $curlResponse = `curl -si ...`;
Will give me the entire header plus the response.
My question is how can I obtain the response body from the server and the http status code in a neat format that allows me to separate them into two separate variables.
Unfortunately I cannot use LWP or any other separate libraries.
Thanks in advance.
-Spencer
I came up with this solution:
URL="http://google.com"
# store the whole response with the status at the and
HTTP_RESPONSE=$(curl --silent --write-out "HTTPSTATUS:%{http_code}" -X POST $URL)
# extract the body
HTTP_BODY=$(echo $HTTP_RESPONSE | sed -e 's/HTTPSTATUS\:.*//g')
# extract the status
HTTP_STATUS=$(echo $HTTP_RESPONSE | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
# print the body
echo "$HTTP_BODY"
# example using the status
if [ ! $HTTP_STATUS -eq 200 ]; then
echo "Error [HTTP status: $HTTP_STATUS]"
exit 1
fi
...Will give me the entire header plus the response.
...in a neat format that allows me to separate them into two separate variables.
Since header and body are simply delimited by an empty line you can split the content on this line:
my ($head,$body) = split( m{\r?\n\r?\n}, `curl -si http://example.com `,2 );
And to get the status code from the header
my ($code) = $head =~m{\A\S+ (\d+)};
You might also combine this into a single expression with a regexp, although this might be harder to understand:
my ($code,$body) = `curl -si http://example.com`
=~m{\A\S+ (\d+) .*?\r?\n\r?\n(.*)}s;
Pretty fundamentally - you're capturing output from a system command. It is far and away better to do this by using the library built for it - LWP.
Failing that though - curl -v will produce status code and content, and you'll have to parse it.
You might also find this thread on SuperUser useful:
https://superuser.com/questions/272265/getting-curl-to-output-http-status-code
Specifically
#creates a new file descriptor 3 that redirects to 1 (STDOUT)
exec 3>&1
# Run curl in a separate command, capturing output of -w "%{http_code}" into HTTP_STATUS
# and sending the content to this command's STDOUT with -o >(cat >&3)
HTTP_STATUS=$(curl -w "%{http_code}" -o >(cat >&3) 'http://example.com')
(That isn't perl, but you can probably use something similar. At very least, running the -w and capturing your content to a temp file.
Haven't figured out a "pure" Perl solution, but I drafted this snippet to check the HTTP response code of a page via curl:
#!/usr/bin/perl
use v5.30;
use warnings;
use diagnostics;
our $url = "";
my $username = "";
my $password = "";
=begin url_check
Exit if HTTP response code not 200.
=cut
sub url_check {
print "Checking URL status code...\n";
my $status_code =
(`curl --max-time 2.5 --user ${username}:${password} --output /dev/null --silent --head --write-out '%{http_code}\n' $url`);
if ($status_code != '200'){
{
print "URL not accessible. Exiting. \n";
exit;
}
} else {
print "URL accessible. Continuing... \n";
}
}
url_check
The verbose use of curl more or less documents itself. My example allows you to pass credentials to a page, but that can be removed as needed.

Format in which the files that are sent as input to curl --data and --data-encode need to written

This works:
curl -k -d 'VARTEST=vartest2&TEXTPARAM=text1%0Atext2&COMMENT=abc22' http://localhost:8080/job/TEST1/buildWithParameters?delay=0sec
curl -X POST -k 'http://localhost:8080/job/TEST1/buildWithParameters?delay=0sec&VARTEST=vartest2&TEXTPARAM=text1%0Atext2&COMMENT=abc22'
I want to be able to write the parameters to -d into a file and run the command line like this
curl -k -d #persargfile 'http://localhost:8080/job/TEST1/buildWithParameters?delay=0sec' -o abc.html
OR like this
curl -k --data-urlencode #persargfile 'http://localhost:8080/job/TEST1/buildWithParameters?delay=0sec' -o abc.html
Question:
What should be the format of the persargfile?
As the man page states, there are several formats available:
ascii (--data-ascii)
urlencoded (--data-urlencoded)
binary (--data-binary)
It looks like for your application the ascii option is required. Meaning your file should contain:
VARTEST=vartest2&TEXTPARAM=text1%0Atext2&COMMENT=abc22

Resources