Force socket blocking mode for Windows/MSYS2 SSL compatibility

Replace Flask's app.run() with manual server creation using Werkzeug's
make_server(). This allows us to explicitly call socket.setblocking(True)
after SSL wrapping to fix errno 11 (EAGAIN) on Windows/MSYS2 where sockets
default to non-blocking mode.

Werkzeug never calls setblocking(True) after wrapping sockets with SSL,
which causes SSL operations to fail on platforms where sockets default to
non-blocking mode. This fix ensures blocking mode is enabled across all
platforms.

Changes:
- Use werkzeug.serving.make_server() instead of app.run()
- Explicitly call server.socket.setblocking(True) after server creation
- Maintain all existing functionality (threaded mode, SSL context, etc.)
- Add detailed comments explaining the Windows/MSYS2 compatibility fix

Co-Authored-By: Thiago Alves <thiagoralves@gmail.com>
This commit is contained in:
Devin AI
2025-10-08 20:25:44 +00:00
parent e52d48c5cf
commit f01c1c05ba

View File

@@ -2672,9 +2672,29 @@ def run_https():
print("Credentials already generated!")
try:
# Create server manually to ensure socket blocking mode for Windows/MSYS2 compatibility
# MSYS2 defaults to non-blocking sockets, which causes SSL operations to fail with
# errno 11 (EAGAIN/EWOULDBLOCK). Werkzeug doesn't call setblocking(True) after
# wrapping the socket with SSL, so we must do it explicitly.
from werkzeug.serving import make_server
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile=str(CERT_FILE), keyfile=str(KEY_FILE))
app_restapi.run(debug=False, host='0.0.0.0', threaded=True, port=8443, ssl_context=context)
server = make_server(
host='0.0.0.0',
port=8443,
app=app_restapi,
threaded=True,
ssl_context=context
)
# Explicitly set socket to blocking mode for Windows/MSYS2 compatibility
server.socket.setblocking(True)
# Log startup and start serving
server.log_startup()
server.serve_forever()
except KeyboardInterrupt as e:
print(f"Exiting OpenPLC Webserver...{e}")
openplc_runtime.stop_runtime()