a subtle bug surfaced when trying multiple individual requests on the
same persistent session, where the connection was being removed from the
watchable connections after each request, but kept in the pool; on the
next request, it would set the same session callbacks; this would go on
and on until connections would get exhausted, after which all of these
callbacks would have to be called.
fixed by having a new callbacks interface, #only, which discards
existing callbacks by type, thereby ensuring there's only one of the
kind.
there was a long-standing buggy workaround, whereas in stream-mode, when
there was no response yet to query from, a synchronous request would be
fired. This would break when under event streams, so we had to document
this as "make sure that...".
This fixes it by implementing a general session API convention, which
separates the step of sending the requests, from waiting for its
receival. And, given that the request knows when the response is
available, we can actually "tick until response".
This might be used in the future to refactor the way we handle the
responses, which buffer the full payload by default, instead of reading
from the connection at will.
while adding tests, found out that io as hash of authority => io wasn't
working due to missing uri extensions. Made sure the same works for unix
sockets.
(This deprecates the :transport_options option)
This should be given an array of peer addresses to connect to. It can be
used when the destination IPs are known and you want to avoid resolving
them, and when the destination is a unix socket (and the destination is
a FS path)
session
In order not to leak these into other sessions, one keeps a registry
around as a session option. This will cascade into the request and
response encoding routines.
connection
After the connection has been upgraded and session is kept open,
subsequent requests were still trying to upgrade it. This fixes it by
marking the connection as upgraded, and falling back to normal
behaviour when it is.
By setting the h2c protocol handler, the rest became much simpler.
Formatting the upgrade request is a matter for the sub-plugin.
Therefore, the specific h2c request upgrade headers are built-in there.
It was observed that, during a request done via a DoH resolve, the
resolver connection is left in the selector, despite already having
resolved the name, until the whole transfer is done. This is
inefficient, as we're not expected to use it again.
Fixed by improvinng the interest calculation of an HTTP/2 connection; if
the connection doesn't have anything to write. and there aren't any
inflight streams nor pings, connection won't be listened on.