Open michalpokusa opened 8 months ago
Does this work in 8.x? (I don't think it does.) I suspect this is simply due to not enough memory. I wouldn't mark this for 9.0.0 because it is a feature addition.
This does work with 8.0.0 on Pico W, but Espressif pieces were not in place until very recently.
possibly related to #8942 ?
On PicoW with the adafruit_httpserver library, after the MemoryError:
is caught in httpserver, gc.mem_free()
shows ~40KB+ free.
Tested an alternate simple-as-possible socket-level HTTPS server (w/o the library)... free memory before the accept call is ~80KB+, and ~50KB+ before the socket close
. But simple requests can be received, and simple responses can be returned.
So it may be a "purely" memory issue (as opposed to something else masquerading as a memory error)... perhaps some combination of CP 9 increased core usage / new memory model + richer adafruit_httpserver library.
@michalpokusa Could you retry with the latest ConnectionManager library? Thanks. https://github.com/adafruit/Adafruit_CircuitPython_ConnectionManager/pull/16 has fixed several other issues that seem similar.
@dhalbert My example code does not use ConnectionManager, adafruit_httpserver
also does not use it.
The issue raises MemoryError on .accept()
on SSLSocket
object, I believe if anything, the CP's ssl
or socket
module might be related, not any Python code.
@michalpokusa Thanks. Currently when you call create_default_context()
it creates an SSL context with all the root certificates loaded, etc., which uses up a lot of RAM. It may be that loading the server cert info pushes things over the top. I did some work on refactoring that, but I'm not sure it's going to help. There are also some ESP-IDF LWIP settings that could be changed.
In CPython, create_default_context()
takes an optional argument that describes whether the context is going to be used for a server or a client socket. If we said server, it could avoid loading some things into RAM it doesn't need to. I started working on adding that arg but there were some complications.
The amount of SRAM actually available on the ESP32-S2 vs S3 is confusing. The datasheets say the S2 has 320kB and the S3 has 512kB. But in the S3 case, it appears the usable RAM might also be 320kB, because part of the RAM is used for memory caches from the flash, etc. I'm still puzzling this out.
@dhalbert Would it be possible to create a ssl context without loading the root certs? I understand it is necessary when we want to request website on public internet, but when creating a local server maybe it might be reasonable to use it with self-signed certs?
I may also be completely wrong about how this works, in that case please correct me.
Would it be possible to create a ssl context without loading the root certs?
Exactly, that's what might help here, if create_default_context()
took the right arg. See purpose
in the CPython version: https://docs.python.org/3/library/ssl.html#ssl.create_default_context. In the HTTPS server example, your certs are self-signed, and you don't need the regular root certs for the client of the server to connect. Is that right? Or, you only need one root cert.
@dhalbert I created my certs using:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout key.pem -out cert.pem
There is also a .load_verify_locations()
method on SSLContext, but as CP's docs says, it is not implemented.
https://docs.circuitpython.org/en/latest/shared-bindings/ssl/index.html#ssl.SSLContext.load_verify_locations
CircuitPython version
Code/REPL
Behavior
This example code should be used with
adafruit_httpserver
from PR https://github.com/adafruit/Adafruit_CircuitPython_HTTPServer/pull/88.When using the HTTP server with SSLSocket the
accept()
method throwsMemoryError
without additional details. The example code works correctly on ESP32-S3 (tested on MatrixPortal S3).Description
Related to:
Additional information
No response