Repository navigation
Add [server] type = cheroot (optional, pure-Python HTTP/1.1 server) - #2270
Conversation
|
The PyPy 3.10/3.11 CI jobs occasionally fail on test_ssl with BufferError: Existing exports of data: object cannot be re-sized. This is a PyPy-specific bug in cheroot: its StreamReader relies on _pyio.RawIOBase.read(), which resizes a buffer in place (del b[n:]) right after ssl.SSLSocket.recv_into() has taken a memoryview over it. On CPython that view is released deterministically, but on PyPy it can stay alive until the next GC run, making the in-place resize fail intermittently. I've opened cherrypy/cheroot#855 with a fix (avoid resizing by returning a sliced copy instead) and a regression test. Once merged and released, bumping the cheroot dependency here will resolve this flakiness; in the meantime, it's a known, non-blocking, intermittent CI failure specific to PyPy+SSL. |
|
EL9 is shipping: python3-cheroot 10.0.1-5.el9 means everything has to work with that version on a hard replacement and there are no plans to start module bundling on EL9 (for EL8 it's a hard requirement). If this cannot be satisfied, imho use of "cheroot" can only be implemented option by using a new toggle named e.g. |
How can I test that? I don't have access to a RHEL (what normal dev does, btw?) The |
https://github.com/Kozea/Radicale/wiki Developer can use "Alma" or "Rocky" as free versions of EL. "-5" is only the revision, normally not including any significant patch. See also: https://src.fedoraproject.org/rpms/python-cheroot Note that Ubuntu 22 LTS also contains only version 8.5 |
|
OK, I will test with those variants. WSGI is a very old and mature spec, I would be very surprized we find incompatibilities with Radicale, be it with very old cheerot version. |
1ddfc5f to
0a253d1
Compare
|
Thanks @pbiering, I reworked the PR along the lines you suggested: it no longer replaces the built-in server. The server test suite is run for both variants ( I dropped the PyPy flakiness note from the description since it only concerns the optional type now. |
|
Somehow it's not passing Test Ubuntu:26 Python:Matrix (ubuntu-26.04, pypy-3.11) Please investigate, thank you! |
|
OK, I looked into it. It's only test_ssl of the cheroot type, and it's a PyPy bug, not a Radicale or cheroot one: cheroot's StreamReader resizes a buffer in place (del b[n:]) right after ssl.recv_into() took a memoryview on it. CPython drops that view immediately, PyPy doesn't, so the resize fails sometimes with a BufferError. I reported it at pypy/pypy#5634. The PyPy folks agreed and fixed _io, but the fix isn't in the 3.11.16 that CI runs on yet. I had a workaround for cheroot, but it meant subclassing a method and copying most of its code. That's worse than the problem, so I didn't submit it. Instead I skipped that single test on PyPy (cheroot type only, builtin and hypercorn still run there), and added a line in the doc. We can drop the skip as soon as CI gets a PyPy with the fix. But I don't know what it means for all your RHEL stuff, those people maintaining old stuff are very, very likely not going to use both a "new" python implementation (pypy) and a new server (cheeroot) for a ~8 years old system. |
409f557 to
2221744
Compare
There was a problem hiding this comment.
please exclude directory .claude from PR
There was a problem hiding this comment.
meanwhile 3.9.1 was released, please rebase
There was a problem hiding this comment.
Please do not overtake old copyrights, only place your's for 2026
2221744 to
c175167
Compare
* New optional server type based on the pure-Python cheroot HTTP server (`pip install radicale[cheroot]`, cheroot>=8.5.0), imported only when asked for, like hypercorn. `builtin` stays the default. * TLS through cheroot's BuiltinSSLAdapter (stdlib ssl): protocol, ciphersuite and mandatory client certificate verification are honoured. * PATH_INFO/QUERY_STRING decoded as UTF-8 by a small WSGI middleware. * IPV6_V6ONLY forced so IPv4/IPv6 "any" can be listened on independently. * Tested against cheroot 8.5.0 and 10.0.1 (EL9). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
cheroot's StreamReader resizes a buffer in place right after ssl.recv_into took a memoryview on it; PyPy does not release the view deterministically, so the resize fails intermittently with BufferError. PyPy fixed `_io` (pypy/pypy#5634); skip until CI has a release with it. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
c175167 to
d128cb4
Compare
Rationale
Following the review discussion, this PR no longer replaces the built-in server. It adds
cherootas a third, optional[server] typenext tobuiltin(still the default) andhypercorn.cheroot is a pure-Python, actively maintained, cross-platform WSGI server (the one CherryPy uses): thread pool, HTTP/1.1 keep-alive, and native TLS through the stdlib
sslmodule.What it does
[server] type = cheroot, installed withpip install radicale[cheroot](cheroot>=8.5.0) or the OS packagepython3-cheroot. It is only imported when asked for, like hypercorn; if missing, the error names the extra.[server]options are honoured:hosts(multiple, IPv4/IPv6),max_connections(thread pool size),timeout,ssl,certificate,key,certificate_authority(mandatory client certs),protocol,ciphersuite.IPV6_V6ONLYis forced so IPv40.0.0.0and IPv6::can be listened on independently.shutdown_socketmechanism.PATH_INFO/QUERY_STRINGare decoded as UTF-8 by a small WSGI middleware (cheroot's nativeGateway_u0is unusable until 🐞 Fix Gateway.gateway_map() to find indirect Gateway subclasses cherrypy/cheroot#854 is released).radicale.log.logger.Compatibility / tests
TestCherootServerRequestsre-runs the wholeTestBaseServerRequestssuite withtype = cheroot(SSL, IPv6, CLI, bind failures, external WSGI server), plus a missing-dependency and a UTF-8 path test. Skipped when cheroot is not installed.prepare_socket()not acceptingreuse_portin old versions, handled.Side note: warning for the built-in server
With the new security context coming (AIs hacking everything, finding vulnerabilities where we did not think there were some), I think Radicale should adopt Django rationale: the internal server is only for local testing, not for production, and it displays a warning at launch saying it is not meant for a production environment. If you are OK with this, I can do the PR.