-
-
Notifications
You must be signed in to change notification settings - Fork 98
Deprecate MakeFile() in favor of StreamReader and StreamWriter
#805
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
feaecac to
4c42a4d
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #805 +/- ##
==========================================
+ Coverage 78.19% 79.49% +1.30%
==========================================
Files 41 42 +1
Lines 4788 5102 +314
Branches 547 566 +19
==========================================
+ Hits 3744 4056 +312
- Misses 905 907 +2
Partials 139 139 |
dad25d2 to
d6a334a
Compare
6407321 to
58938f6
Compare
cheroot/connections.py
Outdated
| raise | ||
|
|
||
|
|
||
| def _make_file_object(sock, mode='r', bufsize=io.DEFAULT_BUFFER_SIZE): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was hoping this trampoline would be made redundant. Why is it necessary? What are the challenges in using the right stream constructors right away?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok maybe this is better. I have jettisoned _make_file_object. HTTPConnection now checks server.ssl_adapter to decide whether to use plain StreamReader/StreamWriter or, if there is one, the SSL adapter's makefile() method. pyopenSSL adapter still needs such a method so that it can offer wrapped streaming methods that know how to deal with WantReadError, WantWriteError etc. The builtin adapter is fine relying on the plain streaming classes.
7e162f6 to
ea44c0b
Compare
MakeFile() in favor of StreamReader and StreamWriter
cheroot/server.py
Outdated
| # Check if SSL adapter needs custom wrapped streaming | ||
| # objects (pyOpenSSL does, builtin doesn't) | ||
| if server.ssl_adapter is not None and hasattr( | ||
| server.ssl_adapter, | ||
| 'makefile', | ||
| ): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like an abstraction leak. We shouldn't make TLS adapters and HTTP connections coupled. Let's think of a better solution. I wonder if this initializer could work with a pre-wrapped socket or something. It doesn't feel right that HTTP layer would care whether TCP's got a TLS tunnel or not.
Also, having a conditionally existing method on adapters seems fragile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm starting to wonder if the server instance would need a makefile() method that would hold the callable selection logic...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is largely what lead to my earlier TLSSocket approach but I've revisited that implementing a more focussed version. The TLSSocket class now wraps the pyOpenSSL SSL.Connection to handle OpenSSL-specific errors like WantReadError internally. This allows plain StreamReader/StreamWriter to work directly now with pyOpenSSL connections. So we get rid of makefile without any abstraction leaks hopefully. See what you think.
cheroot/makefile.py
Outdated
| """ | ||
| File object attached to a socket object. | ||
| This method is now deprecated: Use StreamReader or StreamWriter directly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a function, not a method.
cheroot/server.py
Outdated
| last_used = None | ||
|
|
||
| def __init__(self, server, sock, makefile=MakeFile): | ||
| def __init__(self, server, sock): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing args from method signatures is a breaking API change. They'd need to be deprecated first. Although, I'm not entirely sure how to handle the constructor split beyond that.
1b57f6d to
3ce3eb2
Compare
| # self.socket is of OpenSSL.SSL.Connection type | ||
| resp_sock = self.socket._socket | ||
| # Unwrap to get raw TCP socket | ||
| resp_sock = self.socket._sock |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this attr always exist?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently handle_no_ssl() will only ever get called when using PyOpenSSLAdapter so yes provided we make sure it's there on that adapter this should work. However, the property mimics the same pattern that ssl.SSLSocket uses and also socket.socket.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, it's probably okay for right now. But I hope that in a follow-up we'll be able to have a better way to reach the underlying socket and won't be accessing the private attributes.
3ce3eb2 to
6e99e85
Compare
ff05b9c to
6b422bf
Compare
99e08a1 to
2e54b22
Compare
adb3e86 to
3d15b25
Compare
We replace the `MakeFile` factory function with direct class instantiation. The `MakeFile` function now emits a `DeprecationWarning` and will be removed in a future release. `makefile()` methods are also deprecated on the adapters and its base class.
3d15b25 to
fb4f826
Compare
We replace the
MakeFilefactory function with direct class instantiation. TheMakeFilefunction now emits aDeprecationWarningand will be removed in a future release.The
makefile()methods in the SSL adapters and the baseAdapterclass are also deprecated. These methods are no longer necessary because the adapters now return wrapped sockets that work directly withStreamReaderandStreamWriter.The
pyOpenSSLadapter wraps itsSSL.Connectionobjects in a newTLSSocketclass.TLSSocketimplements a socket interface that handles OpenSSL-specific errors (WantReadError,WantWriteError, etc.). This allows plainStreamReaderandStreamWriterto work transparently withpyOpenSSLconnections.Although its
makefileis no longer used, thebuiltinSSL adapter continues to work essentially as before - Python'sssl.SSLSocketalready provided a compatible interface that works directly withStreamReaderandStreamWriter.This change eliminates the abstraction leak where
HTTPConnectionneeded to call upon an SSL adapter custommakefile()method. Now,HTTPConnectionsimply createsStreamReaderandStreamWriterinstances with whatever socket it receives, whether it's a plain socket,ssl.SSLSocket, orTLSSocket.This is a step towards unifying the two SSL adapters while simplifying higher-level logic.