This is httpdtalk, a tool for talking with a web server.
It has been written for web server diagnostics, especially for checking
http headers produced by cgi scripts.

The usage is:  httpdtalk [options] [host],
see the manual page for more information.

Httpdtalk is one of some simple httpd utilities (named httpd*), which
should be available at the metalab ftp site at
ftp://metalab.unc.edu/pub/Linux/apps/www/misc/.


Some implementation details:
----------------------------
fork() implementation.
Using readline(), I didn't find a way to prevent it from blocking. Thus,
the answer from the server may be sent when the program blocks in the
readline() call. With HTTP the server usually closes the connection
after having sent its answer. But the client cannot perform its close,
since it's blocked. This has a bad consequence: To prevent the server host
from running out of resources due to half-closed connections the server often
resets the connection after a short time. It is not as easy to detect this
by the client (although it's possible). Ignoring the reset connection
the next access to the socket is answered with a SIGPIPE by the kernel.
The signal could be caught, but -- all this would result in an ugly
algorithm, I didn't like it. I wanted the client to prevent its close
immediately after a server close. A SIGPIPE should occur only in extreme
situations.
The solution was to have two processes, one blocking at recv() (actually
read()) and one blocking at readline(). Now the receiving child can close
the socket and exit when encountering EOF, and the parent is informed on
this by SIGCHLD and can exit very normal.

exit() implementation by SIGINT.
My first fork() implementation terminated the parent just in the SIGCHLD
handler. But it seems as if readline() does not like such a termination.
In fact, after beeing terminated this way my shell (bash and thus readline)
behaved very strange. I've had to issue a blind "reset" to get it normal
again. I found out that all becomes well if SIGINT is catched and exits
the parent. -- Thus I use this way for normal termination. Kind of strange
but not too screwed up...

buffering of server's answer.
Starting with a simple receive-write loop for the child, if it writes to a
pipe (echo "GET /" | httpdtalk www.bal.com | less ), it may block in the
write() (to stdout) call causing the kernel receive buffer not to be flushed
(fast enough). This may cause the server to reset the connection and usually
the document is cut. To prevent this, if the output is redirected to a pipe
the child buffers the whole document which, of course, may require a lot of
memory.
In an older implementation I set the output non-blocking and buffered only
when encountering EAGAIN. However, the number of bytes read from the pipe
usually did not match the number of bytes written to it and I didn't find
out for what reason.
