Revert to Flask app.run() and add platform detection to conditionally
enable HTTPS with certificates only on Linux systems. Non-Linux systems
(Windows/MSYS2) skip certificate generation and run HTTP instead to avoid
SSL socket blocking issues.
Changes:
- Use platform.system() to detect Linux vs non-Linux
- Linux: Generate OpenSSL certificates and run HTTPS (unchanged behavior)
- Non-Linux: Skip certificate generation and run HTTP on same port
- Reverted make_server() changes back to app.run()
This provides a pragmatic workaround for Windows/MSYS2 SSL socket
compatibility issues while maintaining full HTTPS functionality on Linux.
Co-Authored-By: Thiago Alves <thiagoralves@gmail.com>
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>
Replace tuple-based ssl_context with explicit ssl.SSLContext creation using
PROTOCOL_TLS_SERVER and load_cert_chain(). This follows Python ssl module
best practices and may handle socket configuration more robustly on MSYS2
where sockets may default to non-blocking mode.
The tuple shortcut (cert, key) internally creates an SSLContext, but using
an explicit SSLContext gives us better control and follows the documented
approach for server-side SSL. This may help with the errno 11 (Resource
temporarily unavailable) issue on Windows/MSYS2.
If this doesn't resolve the issue, we'll need to investigate more invasive
solutions like wrapping Werkzeug's socket creation.
Co-Authored-By: Thiago Alves <thiagoralves@gmail.com>
Flask/Werkzeug's ssl_context parameter expects string paths, not pathlib.Path
objects. On Windows/MSYS2, passing Path objects causes 'Resource temporarily
unavailable' error. Converting to strings maintains Linux compatibility while
fixing Windows support.
Fixes the error reported by user where context showed PosixPath objects
instead of strings, causing Flask to fail on Windows/MSYS2.
Co-Authored-By: Thiago Alves <thiagoralves@gmail.com>
- Replace cryptography library with subprocess calls to openssl CLI
- Use RSA 4096-bit keys for stronger security (vs previous 2048-bit)
- Use SHA256 signature algorithm
- Set certificate validity to 36500 days (~100 years, effectively never expires)
- Maintain same CertGen class interface for backward compatibility
- Remove cryptography dependency from requirements.txt
The OpenSSL-based approach is more universally available across platforms
and doesn't require additional Python dependencies. The certificate is
self-signed and can be used for SSH-like validation of embedded PLC devices.
Co-Authored-By: Thiago Alves <thiagoralves@gmail.com>