Skip to content

M1I10: TlsProxy decorator#65

Merged
s2x merged 2 commits into
mainfrom
feature/m1i10-tlsproxy-decorator
May 2, 2026
Merged

M1I10: TlsProxy decorator#65
s2x merged 2 commits into
mainfrom
feature/m1i10-tlsproxy-decorator

Conversation

@s2x
Copy link
Copy Markdown
Contributor

@s2x s2x commented May 2, 2026

Summary

Action Path
Create src/Server/Socket/TlsProxy.php
Create tests/Server/Socket/TlsProxyTest.php

TlsProxy is a decorator wrapping any SocketProxyInterface to add SSL/TLS encryption:

  • Delegates createSocket() to inner proxy
  • accept() delegates to inner proxy, then socket_export_stream() + stream_socket_enable_crypto() with 30s timeout
  • isSupported() checks function availability
  • Throws SocketCreationException on TLS handshake failure

Acceptance criteria

  • Decorates any SocketProxyInterface
  • accept() calls stream_socket_enable_crypto() with STREAM_CRYPTO_METHOD_TLS_SERVER
  • 30s socket timeout set before TLS handshake
  • isSupported() checks function availability
  • Throws on TLS failure
  • Test passes: validates delegate passthrough, isSupported()

Closes #10

Copy link
Copy Markdown
Contributor Author

@s2x s2x left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary — Round 1

# Severity File:Line Finding
1 MEDIUM src/Server/Socket/TlsProxy.php:44 stream_context_set_option return values unchecked — silent failures
2 LOW src/Server/Socket/TlsProxy.php:51 stream_socket_enable_crypto error details lost via @
3 LOW src/Server/Socket/TlsProxy.php:28 Missing @throws SocketCreationException on accept()

Follow-up Observations

  • Successful TLS handshake test: testAcceptThrowsOnTlsHandshakeFailure covers the failure path, but there's no test for a successful TLS handshake. Consider generating self-signed certs in-memory with openssl_pkey_new() + openssl_csr_sign() for an integration test. File as a separate issue.
  • Cert format docs: The constructor docblock could explicitly mention that cert/key must be PEM-encoded files (matching stream_context_set_option expectations for local_cert/local_pk).

What's Fine ✔️

  • All acceptance criteria from issue #10 and docs/superpowers/milestone-1/08-tls-proxy.md are satisfied
  • Decorator pattern implemented correctly — delegates createSocket() and accept() to inner proxy
  • STREAM_CRYPTO_METHOD_TLS_SERVER used for TLS handshake
  • 30s timeout set via stream_set_timeout before crypto
  • isSupported() correctly checks function_exists for both required functions
  • SocketCreationException thrown on export/handshake failure
  • Tests validate delegate passthrough, isSupported(), and TLS failure path
  • Reflection access on Connection::$resource is safe (the property is readonly \Socket, non-nullable)
  • Error suppression @ on socket_export_stream is safe — immediately followed by === false check

Notes

  • Missing @throws (finding #3): The accept() method throws SocketCreationException on two code paths but has no @throws tag. Other methods in the codebase (e.g. Connection::getPeerName) use @throws annotations. Add @throws SocketCreationException to the method PHPDoc.

Comment thread src/Server/Socket/TlsProxy.php Outdated
Comment thread src/Server/Socket/TlsProxy.php
Copy link
Copy Markdown
Contributor Author

@s2x s2x left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary — Round 2

# Severity File:Line Finding
No new findings. All Round 1 issues resolved.

Follow-up Observations

  • Successful TLS test: testAcceptThrowsOnTlsHandshakeFailure covers failure path, but no test for a successful handshake. Consider using openssl_pkey_new() + openssl_csr_sign() for in-memory self-signed cert generation in a follow-up issue.
  • Stream-based Connection: After socket_export_stream(), the returned Connection wraps a \Socket that should not be used with socket_read()/socket_write() per PHP docs. A stream-aware TlsConnection or equivalent may be needed separately.

What's Fine ✅

  • All 6 acceptance criteria from issue #10 satisfied
  • All 5 acceptance criteria from milestone doc docs/superpowers/milestone-1/08-tls-proxy.md satisfied
  • Round 1 MEDIUM (stream_context_set_option unchecked) — FIXED with explicit return checks
  • Round 1 LOW (stream_socket_enable_crypto error details lost) — FIXED with error_get_last()
  • Round 1 LOW (missing @throws) — FIXED with @throws SocketCreationException docblock
  • Clean decorator pattern, correct delegation
  • Resource cleanup on all failure paths
  • No security issues

@s2x s2x merged commit 0b9ab05 into main May 2, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

M1I08: TlsProxy decorator

1 participant