I use curl to get http headers to find http status code and also return response. I get the http headers with the command
curl -I http://localhost
I was able to get a solution by looking at the curl doc which specifies to use -
for the output to get the output to stdout.
curl -o - http://localhost
To get the response with just the http return code, I could just do
curl -o /dev/null -s -w "%{http_code}\n" http://localhost
Append a line "http_code:200" at the end, and then grep for the keyword "http_code:" and extract the response code.
result=$(curl -w "\nhttp_code:%{http_code}" http://localhost)
echo "result: ${result}" #the curl result with "http_code:" at the end
http_code=$(echo "${result}" | grep 'http_code:' | sed 's/http_code://g')
echo "HTTP_CODE: ${http_code}" #the http response code
In this case, you can still use the non-silent mode / verbose mode to get more information about the request such as the curl response body.
This is a way to retrieve the body "AND" the status code and format it to a proper json or whatever format works for you. Some may argue it's the incorrect use of write format option but this works for me when I need both body and status code in my scripts to check status code and relay back the responses from server.
curl -X GET -w "%{stderr}{\"status\": \"%{http_code}\", \"body\":\"%{stdout}\"}" -s -o - “https://github.com” 2>&1
run the code above and you should get back a json in this format:
{
"status" : <status code>,
"body" : <body of response>
}
with the -w write format option, since stderr is printed first, you can format your output with the var http_code and place the body of the response in a value (body) and follow up the enclosing using var stdout. Then redirect your stderr output to stdout and you'll be able to combine both http_code and response body into a neat output
This command
curl http://localhost -w ", %{http_code}"
will get the comma separated body and status; you can split them to get them out.
You can change the delimiter as you like.
My way to achieve this:
To get both (header and body), I usually perform a curl -D- <url>
as in:
$ curl -D- http://localhost:1234/foo
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json
Date: Wed, 29 Jul 2020 20:59:21 GMT
{"data":["out.csv"]}
This will dump headers (-D
) to stdout (-
) (Look for --dump-header
in man curl).
IMHO also very handy in this context:
I often use jq to get that json data (eg from some rest APIs) formatted. But as jq doesn't expect a HTTP header, the trick is to print headers to stderr using -D/dev/stderr
. Note that this time we also use -sS
(--silent, --show-errors) to suppress the progress meter (because we write to a pipe).
$ curl -sSD/dev/stderr http://localhost:1231/foo | jq .
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json
Date: Wed, 29 Jul 2020 21:08:22 GMT
{
"data": [
"out.csv"
]
}
I guess this also can be handy if you'd like to print headers (for quick inspection) to console but redirect body to a file (eg when its some kind of binary to not mess up your terminal):
$ curl -sSD/dev/stderr http://localhost:1231 > /dev/null
HTTP/1.1 200 OK
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/json
Date: Wed, 29 Jul 2020 21:20:02 GMT
Be aware: This is NOT the same as curl -I <url>
! As -I
will perform a HEAD
request and not a GET
request (Look for --head
in man curl. Yes: For most HTTP servers this will yield same result. But I know a lot of business applications which don't implement HEAD
request at all ;-P
I use this command to print the status code without any other output. Additionally, it will only perform a HEAD request and follow the redirection (respectively -I
and -L
).
curl -o -I -L -s -w "%{http_code}" http://localhost
This makes it very easy to check the status code in a health script:
sh -c '[ $(curl -o -I -L -s -w "%{http_code}" http://localhost) -eq 200 ]'