Add TLS support (upgrade-after-INFO)#57
Open
ChrisFrizza6969 wants to merge 3 commits into
Open
Conversation
Adds client TLS so the driver can connect to TLS-required servers such as
Synadia NGS (tls://connect.ngs.global). Previously the client only spoke
plaintext (CONNECT always sent tls_required:false) and any TLS-required
server reset the connection.
Design:
- Config: new optional `?ClientTlsContext $tls` (null = current plaintext
behavior, fully backward compatible). `fromURI` enables TLS from a
tls:// / nats+tls:// / ssl:// scheme (peer name defaults to the host for
SNI/verification); `fromArray` accepts a `tls` key.
- SocketConnectionFactory: attaches the TLS context to the ConnectContext so
the socket can be upgraded (does NOT connect TLS-first).
- Framer: when TLS is configured, the single reader fiber reads the plaintext
INFO line, runs setupTls(), THEN pushes INFO to the parser. Doing the
upgrade inside the sole socket-reader fiber preserves the single-reader
invariant (amphp forbids concurrent reads); pushing INFO only after the
handshake completes prevents startup() from writing CONNECT mid-handshake.
- SocketConnection::startup() is unchanged (no TLS logic).
Scope/limitation: implements the standard NATS upgrade-after-INFO flow
(server sends plaintext INFO advertising tls_required, client then upgrades).
Servers configured with `tls { handshake_first: true }` are not covered.
Non-TLS code path is byte-for-byte unchanged; existing tests unaffected.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- fromURI tls://, nats+tls://, ssl:// -> ClientTlsContext with host as peer name - non-tls scheme leaves tls null (backward compat) - fromArray accepts a tls key Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add TLS support (upgrade-after-INFO)
Summary
Adds client TLS so the driver can connect to TLS-required servers such as
Synadia NGS (
tls://connect.ngs.global). Currentlythe client only speaks plaintext — it always sends
CONNECTwithtls_required: falseand never performs a TLS handshake — so any server thatadvertises
tls_required: trueresets the connection.Motivation
NGS (and any NATS server with
tls: {...}) sends a plaintextINFOadvertisingtls_required: true, then expects the client to run the TLS handshake beforeCONNECT. Without TLS there is no way to use this driver against those servers.What changed
Config: new optional?Amp\Socket\ClientTlsContext $tls(defaultnull= existing plaintext behavior, fully backward compatible).
fromURIenablesTLS from a
tls:///nats+tls:///ssl://scheme, defaulting the peer nameto the host for SNI/verification;
fromArrayaccepts atlskey.SocketConnectionFactory: attaches the TLS context to theConnectContextso the socket can be upgraded (it does not connect TLS-first).
Framer: when TLS is configured, the single reader fiber reads theplaintext
INFOline, runssetupTls(), and then pushesINFOto theparser. Doing the upgrade inside the sole socket-reader fiber preserves the
single-reader invariant (amphp forbids concurrent reads on a socket); pushing
INFOonly after the handshake completes preventsstartup()(a differentfiber) from writing
CONNECTmid-handshake and corrupting the stream.SocketConnection::startup()is unchanged (no TLS logic).Compatibility
The non-TLS code path is byte-for-byte unchanged: when
$tlsisnull,$upgradeTlsisfalseand theFramerbehaves exactly as before. Existingtests are unaffected.
Scope / limitation
Implements the standard NATS upgrade-after-
INFOflow. Servers configured withtls { handshake_first: true }(TLS handshake beforeINFO) are not covered bythis PR.
Tests
ConfigTestcases:tls:///nats+tls:///ssl://produce aClientTlsContextwith the host as peer name; a non-TLS scheme leavestlsnull;
fromArrayaccepts atlskey.php-cs-fixer(no diff),phpunitConfigTestgreen,phpstanlevel max / strict clean on the changed files.INFO→setupTls()→CONNECT→PONG, plus JetStream object store list/get/putover the resulting TLS connection.