I observe following scenario in WireShark:
The problem I see here is that after receiving [FIN, ACK]
from server (4090) and acknowledging it (4092), http client attempts to send another HTTP request instead of immediately close (and probably reestablish) TCP connection. It looks like [FIN, ACK]
is simply ignored by HTTP clients.
According to RFC 7230 (6.3), HTTP protocol specifies it's oven mechanism for persistent connection management using Connection
headers. It works just fine, since it supported by both clients and servers.
However HTTP is usually run on top of TCP. TCP connection management have no idea about protocol on top and can be used independently from HTTP. But HTTP clients doesn't support handling this (and probably they shouldn't, it should be supported on socket level). However servers do utilize it, because it allows to gracefully close connection without sending additional HTTP request. For example nginx sends FIN
package, when connection is timed out or on configuration reload.
NOTE When HTTP client receives RST
from server it closes connection. And it seems to be done on socket level, since I can't find anything related to this in HTTP clients' source code.
- Is my understanding of situation correct? Ignoring
FIN
message by clients, while servers use it, seems to be completely wrong. - Why
RST
is handled on socket level, butFIN
is not? - Is there any RFC/other standard on how HTTP clients should handle TCP connection closing?
- Is it nginx doing something non-standard or HTTP clients doesn't follow standard?
PS I'm able to reproduce it using HTTP clients in Python 2/3, Java and httperf
utility written in C. So I believe it's common for HTTP clients to ignore FIN
message. I want to understand why.