It's important to remember that once a TCP connection is established, it is bidirectional, but that each direction can be shut down independently.
If peers C and S are communicating using TCP, then C can shut down its stream to S without affecting S's stream to C by sending a packet with the FIN bit set. On Unix, C can make that happen by calling shutdown(fd,1). When S receives the FIN packet, it knows that C is done sending, but S can continue sending data to C. On Unix, if S calls read on the TCP socket, it will get EOF (read will return 0) after read returns any remaining buffered data. When C sends the FIN, it is not telling S that it wants S to stop sending data. It's perfectly valid for C to send an HTTP request immediately followed by a FIN, and then wait for S to send the HTTP response. Now, suppose C sends the HTTP request and then wants to tell S to abort the request. It doesn't matter whether C has sent the FIN or not: even if C has not sent the FIN (meaning that C can send more data to S), HTTP does not provide any way for C to ask S to abort. At the TCP level, if C sends the FIN, it doesn't mean that S should stop processing and sending. It just tells S that C is done sending. To tell S to abort, the best C can do is send a packet with the RST flag set. On Unix, C can do that by setting SO_LINGER on with a linger time of zero and then closing the socket. If S is on a Unix system, then when its TCP stack receives the RST, the TCP stack won't immediately notify the process. The process must try to write to the TCP socket; it will then receive a SIGPIPE. If SIGPIPE is blocked or ignored, or if the SIGPIPE handler returns, then the write system call will return EPIPE. I think I've read that on some Unix systems, if you call write with 0 bytes, it will return EPIPE (or raise SIGPIPE) if a RST has been sent. I think I've read that on Linux this does not work. I haven't tested it. So how can we use all of this knowledge to allow an AOLserver handler to detect when the client has cancelled (sent an RST)? Simple: try to send a byte periodically; if ns_write returns 0, then the client has gone away. There's no other portable, reliable way to do it. Note that if you send the response with ns_return, you can't use ns_write. And if you use ns_write to send the HTTP header, then AOLserver will not allow HTTP keepalive.
