Issue
I am working on providing support for sending http post requests from one of our tools. The tool basically executes a job via http requests.
The way this is achieved is the tool makes a call to RunScript.bat with a number of arguments. The script parses these args and makes a curl post request after validation. The Post request is handled by our internal Java Service.
What I want is my batch file should be able to fetch the Response Code (200/409 etc.) of the post request and based on this, the script should return 1 or 0 as exit value back to the tool. The tool then marks the job pass/fail based on the return value.
Tool: Parses the returned value
RunScript.bat arg1 arg2 arg3
RunScript.bat
@echo off
SETLOCAL
ECHO %DATE% %TIME% Calling %0 with %*
SET "SCRIPT_DIR=%~dp0"
ECHO Script Dir %SCRIPT_DIR%
SET cmd=%1
SET val2=%2
SET val3=%3
%SCRIPT_DIR%\curl -v -X POST http://localhost:9500/%cmd%/%val2%/%val3%
Is it possible to fetch the Response Code of the curl request in the batch script and then return 1/0 based on the Response Code ?
Solution
The first thing we need is to get curl
to output the HTTP status. For this I used pvandenberk's answer to Getting curl to output HTTP status code?. Next, we have to get that output into an environment variable so we can test it. For this we use the for /f %%a in ( 'command-to-execute' ) do ...
form of the for
command (see for /?
for more details).
Incorporating these (and some other minor tweaks), something like the following should help:
@echo off
SETLOCAL
ECHO %DATE% %TIME% Calling %0 with %*
SET "SCRIPT_DIR=%~dp0"
ECHO Script Dir %SCRIPT_DIR%
SET "cmd=%1"
SET "val2=%2"
SET "val3=%3"
SET "URL=http://localhost:9500/%cmd%/%val2%/%val3%"
SET HTTP=
for /f %%a in ( '"%SCRIPT_DIR%\curl" -s -o nul -v -X POST -w "%%{http_code}" "%URL%"' ) do set HTTP=%%a
if "%HTTP%" == "200" (
exit /b 0
) else (
exit /b 1
)
Notes:
I've assumed
cmd
,val2
andval3
in your original URL were meant to be replaced with the contents of the earlier environment variables, so have changed them to%cmd%
etc. when buildingURL
.In the
for
statement, the whole of the command to be executed is enclosed in single-quotes ('.....'
).I've wrapped the invocation of curl in double-quotes (
"%SCRIPT_DIR%\curl"
): this should allow it to work even if the script-directory were to contain spaces.I've added
-s
(silent) and-o nul
(where to send the full response) to curl's command-line. This will help to ensure any output returned from thePOST
request does not interfere with the HTTP status code. If you need to see this output, use-o filename
andTYPE
the file before making the test onHTTP
.The percent-sign in
-w "%%{http_code}"
needs to be doubled because it has special meaning to the shell.The output of
-v
(verbose) is sent tostderr
so shouldn't interfere with capturing the HTTP response code.
Update
To get both the HTTP response code, and still see the output from the curl command itself you could try replacing the for /f ...
line above with the one below:
for /f "delims=" %%a in ( '"%SCRIPT_DIR%\curl" -v -X POST -w "%%{http_code}" "%URL%"' ) do set "HTTP=%%a" && echo %%a
The
"delims="
means that the lines of output from curl will not be split into separate tokens so%%a
will hold the whole of each line.I've removed the
-s
and-o nul
options, so the original output from curl will still be generated.The
set "HTTP=%%a"
command has had double-quotes added to prevent trailing spaces being added to the environment variable. Because the response code (e.g. 404) is the last line emitted by curl, the final value ofHTTP
will still be what we want.The
echo %%a
will replay all lines generated by curl.
Answered By - TripeHound