Replies: 5 comments 2 replies
-
When thinking about this a bit more, it sounds like having an |
Beta Was this translation helpful? Give feedback.
-
I've just opened a draft PR that exposes the functionality I need as a public interface #274 in what I think is a suitable implementation. Happy to hear your thoughts on the approach and whether there's anything you wish to change or another approach you recommend. |
Beta Was this translation helpful? Give feedback.
-
One thing that hits me looking at #274 and our code is that, although See: httpcore/httpcore/_async/connection_pool.py Lines 201 to 226 in 12a25fd In here we do a dance to acquire an existing connection from the pool, create one if needed, send a request, and then remove the connection from the pool. If |
Beta Was this translation helpful? Give feedback.
-
@jborean93 About #274 and the "allow connections to open their sockets via a dedicated method" idea… Also, cc @tomchristie — happy to hear your thoughts about this? Circling back to my last point above, actually transports are really thought of as classes with two methods: @asynccontextmanager
async def open_something():
socket = await open_socket()
something = Something(socket)
try:
yield something
finally:
await something.aclose() Which is used like this: async with open_something() as something:
... But although our transports expose the same kind of "constructor + For example, So, we could switch to a style in which we have To customize "open socket" behavior, one would have to either override from httpcore._async.http import AsyncHTTPConnection
async def open_custom_socket(...):
...
socket = await open_custom_socket(...)
conn = AsyncHTTPConnection(socket=socket, origin=...)
response = await conn.arequest(...) @jborean93 What would be the impact of this on your use case? |
Beta Was this translation helpful? Give feedback.
-
Yea there seems to be a mixture of transport behaviours but ultimately it does things right. The reason why I thought adding
I can't really question how things work here as I'm mostly fumbling around but this is what I see with the 3 classes of transports being used by
So we already do have actual instances where we pass in a socket (ignoring tunneled proxies) I was mostly just trying to mirror the close method with the relevant open functionality that a transprot may or may not implement.
Whatever route you would like to go forward I'm happy to follow, all I need is a way to open the connection and do the TLS handshake before I prepare my actual HTTP request. Right now that's impossible to do without calling some private methods, or re implementing the whole shebang. Still what you have in that PR will work for my scenario, I can manually create and connect to the socket myself, the next step is to just make the connection class public :) (totally understand why the project is not prepared to do that right now).
The method you have chosen works for my use case and I will be happy to adopt it once the underlying connection is made public. For now I've just re implemented (shamelessly copied) |
Beta Was this translation helpful? Give feedback.
-
I've working on an custom httpx transport which uses Kerberos/NTLM/Negotiate authentication when talking to a peer. These authentication methods have a custom extension when talking over TLS called channel binding tokens (CBT) where you embed a structure that is based on information from the TLS context which in essence binds the authentication against the TLS context making it harder to achieve MitM attacks.
A version of CBT that I'm currently using is documented in RFC 5929 which is essentially
tls-server-end-point:<cert hash>
. In the past I've just send a request to the host, gotten the SSL object from the socket in the response but this has a few problems:The last point is problematic because in my scenario I send a blank request which sets up a connection and the response I get back is a 401. Typically I've seen a
Connection: close
header which has the*ConnectionPool
classes drop the connection from the pool. This means the next request is a brand new connection with a brand new negotiated TLS context.For the
tls-server-end-point
I could still get the certificate hash as that should be static between the connections but with new protocols like TLS 1.3 the draft proposal for CBT seems to indicate it's based on the unique connection set up Breaking authentication.What I'm hoping is for is to expose the _open_socket method publically in some shape or form. This would allow me to create the socket connection and set up the TLS request before I send a request through
(s)request
on the connection. I feel like this could potentially be done by setting up the socket myself and passing it into the__init__()
for*HTTPConnection
or by just making that method more public by removing the_
. This also hinges on my other question around whether connections are actually meant to be publicly exposed in #272.Very interested to hear your thoughts on this as I do have a working prototype for all this but it relies on being able to access
AsyncHTTPConnection
and calling_open_socket
manually before sending the request through(a)request
.Beta Was this translation helpful? Give feedback.
All reactions