Doing TCP/HTTP with Bash

Bash have the ability to do I/O on TCP sockets through the special file « /dev/tcp/<host>/<port> ».

Here is a simple setup that demonstrate this capability by implementing a simple HTTP client.

#!/bin/bash

if [ $# -ne 3 ]; then
	echo "Usage:"
	echo "  $0 <host> <port> </resource/to/get>"
	echo ""
	exit
fi

HOST=$1
PORT=$2
RESOURCE=$3

# Connect fd#3 to the TCP socket
exec 3<> "/dev/tcp/$HOST/$PORT"

# Send request to fd 3
echo -n -e "GET $RESOURCE HTTP/1.1\r\n" 1>&3
if [ "$PORT" = "80" ]; then
	echo -n -e "Host: $HOST\r\n" 1>&3
else
	echo -n -e "Host: $HOST:$PORT\r\n" 1>&3
fi
echo -n -e "Connection: close\r\n" 1>&3
echo -n -e "\r\n" 1>&3

# Read HTTP status line from fd 3
read STATUS 0<&3
STATUS=$(echo "$STATUS" | tr -d '\r\n')
echo "Status [[[$STATUS]]]" 1>&2

# Read the HTTP headers from fd 3
while read HEADER 0<&3; do
	HEADER=$(echo "$HEADER" | tr -d '\r\n')
	if [ "$HEADER" = "" ]; then
		break
	fi
	echo "Header [[[$HEADER]]]" 1>&2
done

# Only handle HTTP 200
if [ "${STATUS:9:3}" != "200" ]; then
	echo "Server responded with an unexpected status code [[[$STATUS]]]" 1>&2
	exit
fi

# Print the HTTP response data
cat 0<&3
Ce contenu a été publié dans code. Vous pouvez le mettre en favoris avec ce permalien.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*