curl 400 bad request (in bash script) - bash

I trying to do execute the following script in bash
#!/bin/bash
source chaves.sh
HEAD='"X-Cachet-Token:'$CACHET_KEY'"'
SEARCH="'{"'"status"'":1,"'"id"'":"'"7"'","'"enabled"'":true}'"
echo $SEARCH
if curl -s --head --request GET http://google.com.br | grep "200 OK" > /dev/null; then
echo 'rodou'
curl -X PUT -H '"Content-Type:application/json;"' -H '"'X-Cachet-Token:$CACHET_KEY'"' -d $SEARCH $CACHET_URL/7
else
echo 'não deu'
curl -X PUT -H '"Content-Type: application/json;"' -H $x -d '{"status":1,"id":"7","enabled":true}' $CACHET_URL/7
fi
But keep receiving a 400 bad request from the server.
When i try to run the same line (echo in the script, Ctrl+c and Ctrl+v) directly in terminal, the command run without problems.
The source file have the directions to path and a variable token i need to use, but as far as i have tested is reading ok.
edit 1 - hidding some sensitive content
edit 2 - posting the exit line (grabed trought Ctrl+c, Ctrl+v)
The command i neet to input in server is:
curl -X PUT -H "Content-Type:application/json;" -H
"X-Cachet-Token:4A7ixgkU4hcCWFReQ15G" -d
'{"status":1,"id":"7","enabled":true}'
http://XXX.XXX.XXX.XXX/api/v1/components/7
And the exit i grabed trought echo comand, give me the exact exit i want, but don't run inside script, only outside.
I'm a bit new to the curl, any help can be apreciate.
Sorry for the bad english and tks in advance.

Related

curl 400 bad request for bash script

I am trying to run a curl command within a bash, when running the curl outside separately its working fine, but same running with Bash throws bad request 400 error. Would appreciate if someone can point where I am going wrong
#!/bin/bash
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
curl http://localhost/cron/abc -H 'content-type: application/json'
echo 'Cron Executed at:' "$TIMESTAMP" | tee /var/log/cron.txt

curl --fail without suppressing stdout

I have a script that uploads a file to a WebDav server using curl.
curl --anyauth --user user:password file http://webdav-server/destination/
I want two things at the same time:
have the script output to stdout (which is directed to a log file)
detect whether the upload succeeded
As far as I know, curl returns an exit code of 0 even in 401(unauthorized) or 407(conflict) situations. The --fail option can be used to change this behavior, but it suppresses stdout.
What would be the best workaround for this? tee and grep?
curl writes its output to stderr(2), the error stream instead of stdout(1). Redirect it on the command using 2>&1
curl --fail --anyauth --user user:password file http://webdav-server/destination/ 2>&1 > logFile
retval=$?
if [ $retval -eq 0 ]; then
echo "curl command succeeded and the log present in logFile"
fi

Login via curl fails inside bash script, same curl succeeds on command line

I'm running this login via curl in my bash script. I want to make sure I can login before executing the rest of the script, where I actually log in and store the cookie in a cookie jar and then execute another curl in the API thousands of times. I don't want to run all that if I've failed to login.
Problem is, the basic login returns 401 when it runs inside the script. But when I run the exact same curl command on the command line, it returns 200!
basic_login_curl="curl -w %{http_code} -s -o /dev/null -X POST -d \"username=$username&password=$password\" $endpoint/login"
echo $basic_login_curl
outcome=`$basic_login_curl`
echo $outcome
if [ "$outcome" == "401" ]; then
echo "Failed login. Please try again."; exit 1;
fi
This outputs:
curl -w %{http_code} -s -o /dev/null -X POST -d "username=bdunn&password=xxxxxx" http://stage.mysite.it:9301/login
401
Failed login. Please try again.
Copied the output and ran it on the cmd line:
$ curl -w %{http_code} -s -o /dev/null -X POST -d "username=bdunn&password=xxxxxx" http://stage.mysite.it:9301/login
200$
Any ideas? LMK if there's more from the code you need to see.
ETA: Please note: The issue's not that it doesn't match 401, it's that running the same curl login command inside the script fails to authenticate, whereas it succeeds when I run it on the actual CL.
Most of the issues reside in how you are quoting/not quoting variables and the subshell execution. Setting up your command like the following is what I would recommend:
basic_login_curl=$(curl -w "%{http_code}" -s -o /dev/null -X POST -d "username=$username&password=$password" "$endpoint/login")
The rest basically involves quoting everything properly:
basic_login_curl=$(curl -w "%{http_code}" -s -o /dev/null -X POST -d "username=$username&password=$password" "$endpoint/login")
# echo "$basic_login_curl" # not needed since what follows repeats it.
outcome="$basic_login_curl"
echo "$outcome"
if [ "$outcome" = "401" ]; then
echo "Failed login. Please try again."; exit 1;
fi
Running the script through shellcheck.net can be helpful in resolving issues like this as well.

Why is this bash/CURL call to REST services giving inconsistent results with parameters?

I have written a smoke-testing script that uses BASH script & Curl to test RESTful web services we're working on. The script reads a file, and interprets each line as a URL suffix and parameters for a Curl REST call.
Unfortunately, the script gives unexpected results when I adapted it to run HTTP POST calls as well as GET calls. It does not give the same results running the command on its own, vs. in script:
The BASH Script:
IFS=$'\n' #Don't split an input URL line at spaces
RESTHOST='hostNameAndPath' #Can't give this out
URL="/activation/v2/activationInfo --header 'Content-Type:Application/xml'"
URL2="/activation/v2/activationInfo"
OUTPUT=`curl -sL -m 30 -w "%{http_code}" -o /dev/null $RESTHOST$URL -d #"./activation_post.txt" -X POST`
echo 'out:' $OUTPUT
OUTPUT2=`curl -sL -m 30 -w "%{http_code}" -o /dev/null $RESTHOST$URL2 --header 'Content-Type:Application/xml' -d #'./activation_post.txt' -X POST`
echo 'out2:' $OUTPUT2
Results Out:
out: 505
out2: 200
So, the first call fails (HTTP return code 505, HTTP Version Not Supported), and the second call succeeds (return code "OK").
Why does the first call fail, and how do I fix it? I've verified they should execute the same command (evaluating in echo). I am sure there is something basic I'm missing, as I am just NOW learning Bash scripting.
I think I have found the problem! It is caused by IFS=$'\n'! Because of this, variable expansion does not work as expected. It does not let to split the arguments specified in the URL string!
As a result the SERVER_PROTOCOL variable on the server side will be set to '--header Content-Type:Application/xml HTTP/1.1' instead of "HTTP/1.1", and the CONTENT_TYPE will be 'application/x-www-form-urlencoded' instead of 'Application/xml'.
To show the root of the problem in detail:
VAR="Solaris East"
printf "+%s+ " $VAR
echo "==="
IFS=$'\n'
printf "+%s+ " $VAR
Output:
+Solaris+ +East+ ===
+Solaris East+
So the $VAR expansion does not work as expected because of IFS=$'\n'!
Solution: Do not use IFS=$'\n' and replace space to %20 in URL!
URL=${URL2// /%20}" --header Content-Type:Application/xml"
In this case your first curl call will work properly!
If You still use IFS=$'\n' and give --header option in the command line it will not work properly if URL contains a space, because the server will fail to process it (I tested on apache)!
Even You still cannot use HEADER="--header Content-Type:Application/xml" as expanding $HEADER will result one(!) argument for curl, namely --header Content-Type:Application/xml instead of splitting them into two.
So I may suggest to replace spaces in URL to %20 anyway!
The single quotes surrounding Content-Type:Application/xml, because they are quoted in the value of URL are treated as literal quotes and not removed when $URL is expanded in that call to curl. As a result, you are passing an invalid HTTP header. Just use
URL="/activation/v2/activationInfo --header Content-Type:Application/xml"
OUTPUT=`curl -sL -m 30 -w "%{http_code}" -o /dev/null $RESTHOST$URL -d #"./activation_post.txt" -X POST`
However, it's not a great idea to rely on word-splitting like this to combine two separate pieces of the call to curl in a single variable. Try something like this instead:
URLPATH="activation/v2/activationInfo"
HEADERS=("--header" "Content-Type:Application/xml")
OUTPUT=$( curl -SL -m 30 -w "%{http_code}" -o /dev/null "$RESTHOST/$URL" "${HEADERS[#]}" -d #'./activation_post.txt' -X POST )

Run curl from .sh script with defined Content-Type

When I'm trying to run test.sh script I've always receive error from curl:
curl: (6) Couldn't resolve host 'application'
test.sh:
#!/bin/sh
CT="Content-Type:\ application/json"
TEST="curl http://127.0.0.1 -H $CT"
echo $TEST
RESPONSE=`$TEST`
echo $RESPONSE
But if I just run following command from console everything fine:
curl http://127.0.0.1 -H Content-Type:\ application/json
Could you please let me know what is wrong in script, as I understand something is wrong with 'space' escape, but have no idea how to fix it.
Also I've tried following combination, but result the same:
CT="Content-Type: application/json"
TEST="curl http://127.0.0.1 -H \"$CT\""
UPD:
bash / dash is only available on server. (/bin/sh --> bash)
GNU bash, version 4.2.10(1)-release (x86_64-pc-linux-gnu)
Run the following: (delete the space after Content-Type)
#!/bin/bash
CT="Content-Type:application/json"
TEST="curl http://127.0.0.1 -H $CT"
echo $TEST
RESPONSE=`$TEST`
echo $RESPONSE
You can try with: bash -c your_bash_file.sh It worked for me with the same problem

Resources