What I Want:
After a successful connection, I want curl to exit successfully. I am running this command inside a container, so I want the curl command to exit successfully so that the container will too.
Here is my example:
$ curl -v telnet://google.com:443/
* Trying 172.217.197.113...
* TCP_NODELAY set
* Connected to google.com (172.217.197.113) port 443 (#0)
Options I have tried:
No Keep Alive:
$ curl -v --no-keepalive telnet://google.com:443/
* Trying 172.217.197.102...
* TCP_NODELAY set
* Connected to google.com (172.217.197.102) port 443 (#0)
Connection Timeout:
$ curl -v --connect-timeout 5 telnet://google.com:443/
* Trying 172.217.197.139...
* TCP_NODELAY set
* Connected to google.com (172.217.197.139) port 443 (#0)
Keep Alive Time:
$ curl -v --keepalive-time 5 telnet://google.com:443/
* Trying 172.217.197.139...
* TCP_NODELAY set
* Connected to google.com (172.217.197.139) port 443 (#0)
Flag Definitions
--no-keepalive (Disable keepalive use on the connection)
--connect-timeout (SECONDS Maximum time allowed for connection)
--keepalive-time (SECONDS Wait SECONDS between keepalive probes)
To make curl exit immediately upon a successful telnet connection, purposely pass an unknown telnet option and test if the exit code is 48:
curl --telnet-option 'BOGUS=1' --connect-timeout 2 -s telnet://google.com:443 </dev/null
code=$?
if [ "$code" -eq 48 ]; then
echo "Telnet connection was successful"
else
echo "Telnet connection failed. Curl exit code was $code"
fi
We purposely passed an unknown telnet option, BOGUS=1
, to curl's -t, --telnet-option
option. Replace BOGUS
with any name you want other than the three supported options of TTYPE
, XDISPLOC
, or NEW_ENV
.
48 is curl's error code for "CURLE_UNKNOWN_OPTION (48) An option passed to libcurl is not recognized/known."
This works because the telnet options are processed only after a successful connection.
Purposely pass a telnet option with bad syntax, such as BOGUS
or an empty string, and test for an exit code of 49 (CURLE_SETOPT_OPTION_SYNTAX). We use this approach in the following function. As before, this works because curl processes the telnet options only after a successful connection.
# Args:
# 1 - host
# 2 - port
tcp_port_is_open() {
local code
curl --telnet-option BOGUS --connect-timeout 2 -s telnet://"$1:$2" </dev/null
code=$?
case $code in
49) return 0 ;;
*) return "$code" ;;
esac
}
tcp_port_is_open example.com 80
echo "$?"
# 0 ✔️
tcp_port_is_open example.com 1234
echo "$?"
# 28 - Operation timeout ✔️
tcp_port_is_open nonexistent.example.com 80
echo "$?"
# 6 - Couldn't resolve host. ✔️
https://curl.se/docs/todo.html#exit_immediately_upon_connection
Via: https://curl.se/mail/archive-2022-04/0027.html