I am trying to write a simple bash script that is listening on a port and responding with a trivial HTTP response. My specific issue is that I am not sure if the port is available and in case of bind failure I fall back to next port until bind succeeds.
So far to me the easiest way to achieve this was something like:
for (( i=$PORT_BASE; i < $(($PORT_BASE+$PORT_RANGE)); i++ ))
do
if [ $DEBUG -eq 1 ] ; then
echo trying to bind on $i
fi
/usr/bin/faucet $i --out --daemon echo test 2>/dev/null
if [ $? -eq 0 ] ; then #success?
port=$i
if [ $DEBUG -eq 1 ] ; then
echo "bound on port $port"
fi
break
fi
done
Here I am using faucet from netpipes Ubuntu package.
The problem with this is that if I simply print "test" to the output, curl complains about non-standard HTTP response (error code 18). That's fair enough as I don't print HTTP-compatible response.
If I replace echo test with echo -ne "HTTP/1.0 200 OK\r\n\r\ntest", curl still complains:
user@server:$ faucet 10020 --out --daemon echo -ne "HTTP/1.0 200 OK\r\n\r\ntest"
...
user@client:$ curl ip.of.the.server:10020
curl: (56) Failure when receiving data from the peer
I think the problem lies in how faucet is printing the response and handling the connection. For example if I do the server side in netcat, curl works fine:
user@server:$ echo -ne "HTTP/1.0 200 OK\r\n\r\ntest\r\n" | nc -l 10020
...
user@client:$ curl ip.of.the.server:10020
test
user@client:$
I would be more than happy to replace faucet with netcat in my main script, but the problem is that I want to spawn independent server process to be able to run client from the same base shell. faucet has a very handy --daemon parameter as it forks to background and I can use $? (exit status code) to check if bind succeeded. If I was to use netcat for a similar purpose, I would have to fork it using & and $? would not work.
Does anybody know why faucet isn't responding correctly in this particular case and/or can suggest a solution to this problem. I am not married neither to faucet nor netcat but would like the solution to be implemented using bash or it's utilities (as opposed to write something in yet another scripting language, such as Perl or Python).