This should complement the `:origin` option, in order to provide good
defaults to build REST SDKs around of.
Ex:
```ruby
HTTPX.with(origin: "https://api.this-product.com", base_path: "/v3.1")
```
In order to expose other auth schemes in proxy, the basic, digest and
ntlm modules were extracted from the plugins, these being left with the
request management. So now, an extra parameter, `:scheme`, can be
passed (it'll be "basic" for http and "socks5" for socks5 by default,
can also be "digest" or "ntlm", haven't tested those yet).
a regression from the 0.19.x series was omitting the proxy credentials
when passed directly as proxy options (instead of being part of the URI).
Closes#188
class overrides
the faraday adapter was relying on subclassing the session to load
custom plugins. this doesn't play well with other integrations
monkeypatching the original session class, such as datadog or webmock,
which redefine it. from now on, we not only defer the creation of the
custom until necessary, we also use Session#plugin
Fixes#187
previously, a connection could be created based on request options. The
main problem is that requests may have special headers, which would make
them assign its own connection due to the headers mismatch in headers to
the already open connection to the same origin. This, in certain
scenarios, coupled with the persistent plugin, cascades into multiple
connections to the same host which are never closed.
This fix ensures that connection initial options comes from the session.
This way, it'll never change (as connections exhaust). Alongside that,
matching headers was relaxed to only take into account headers which the
original connection knows, special request headers will then opt out
from this.
* Webmock allows users to stub a request using a URI with query
parameters, as a shortcut instead of using `with...`
* The Webmock adapter did not construct a URI that included the
`request.query`, causing stubs that had the same host/path, but
different queries, to return incorrect results
This type of lookup was guarded in the first DNS query lookup, however
after recursive CNAME queries, this could trigger a case where an AAAA
query would fetch cached A records, which would be filtered out but
still delivered.
Closs #184
when the early resolve path (using IP, /etc/hosts IP, IP from cache) is
followed, emit_addresses is called, and in a particular case (dual-stack
network but using an IPv4 address), the happy eyeballs resolution delay
path was activated when it shouldn't (it's meant to be used only for DNS
network requests), and resulted in @pool being called before it was ever
set.
This simple check ensures that it doesn't happen before it must.
Closes#182
for multi-backed resolvers, resolving is attempted before sending it to
the resolver. in this way, cached, local or ip resolves get
propagated to the proper resolver by ip family, instead of the
previous mess.
the system resolver doesn't do these shenanigans (trust getaddrinfo)
the early_resolve can't rely on separate by-family resolve logic.
Therefore, the addresses coming from there should be emitted with the
proper sort (ipv6 addresses last).
Also, fixed an issue with tcp connect where the socket wasn't being
reinitialized before the new attempt, thereby retrying to connec on the
same address that failed.
the ruby `resolver` library does everthing in ruby, and sequentially
(first ipv4 then ipv6 resolution). we already have native for that, and
getaddrinfo should be considered the ideal way to use DNS (potentially
in the future, it becomes the default resolver).
Two resolver are kept (IPv6/IPv4) along in the pool, to which all
names are sent to and read from in the same pool. IPv4 resolves are
subject to a 50ms delay (as per rfc) before they're used for connecting.
IPv6 addresses have preference, in that if they arrive before the delay,
they are immediately used. If they arrive after the delay, they do not
interrupt the connection, but they'll be the next-in-line in case
connection handshake fails.
Two resolvers are kept, but the inherent Connection will be shared,
thereby sending name resolving requests to the same HTTP/2 connection in
bulk. The resolution delay logic from above also applies.
Currently handles resolving via `resolv` lib. This happens synchronously
though, so we're not there yet.