Hi, I'm experimenting an annoying issue when a server disconnects a TCP
connection established by a Ruby client.
Let me start with an example of what I consider the expected behavior:
a) Using Linux "telnet" command:
- First connect to google.com:
~$ telnet google.com 80
Trying 209.85.229.106...
Connected to google.com.
Escape character is '^]'.
- Then write something ("hello\n"):
hello
- So I receive a 400 response:
HTTP/1.0 400 Bad Request
[...]
- And a warning:
"Connection closed by foreign host."
- telnet exits with status 1 due to the remote disconnection error.
b) Using Ruby 1.9.1 TCPSocket:
- First connect:
> require "socket"
true
> socket = TCPSocket.new("google.com", 80)
#<TCPSocket:0x00000001010288>
- Now netstat shows the connection as ESTABLISHED (ok).
- Write "hello\n" into the socket:
> socket.puts "hello"
nil
- I receive the same 400 response from the www server. Now netstat shows the
connection as CLOSE_WAIT (OK?).
- Write "hello\n" again (IMHO it should fail):
> socket.puts "hello"
nil <---- didn't raise !!!
- Doing a ngrep I see that irb has sent "hello\n" over the previous TCP
connection but this time it doesn't receive response from the www server. This
is, irb is using a closed connection!:
T 2010/01/12 20:12:04.072705 192.168.1.10:35272 -> 209.85.229.105:80 [AP]
hello
···
#
- But after this new "puts" now netstat shows nothing! (no connection => OK).
- Repeat again:
> socket.puts "hello"
Errno::EPIPE: Broken pipe
from (irb):6:in `write'
from (irb):6:in `puts'
from (irb):6
from /usr/bin/irb:12:in `<main>'
- Now it raises!
Why didn't Ruby raise in the second "puts" attemp??? the server already closed
the connection! Why does Ruby realize of it after a new retry?
Well, this issue causes one request lost (the second one) since there is no
way to know if the server accepted or dropped the request.
Is it a bug? is there a way to check the socket connection before sending
(loosing in fact) a request? (TCPSocket#closed? is not valid here as it just
returns true in case *we* have closed a socket).
Thanks a lot for any help.
--
Iñaki Baz Castillo <ibc@aliax.net>