Repository navigation
Conversation
A connection with an SSL context requires TLS to every server, but a ws:// server is a plain websocket that is never upgraded, so it would be reached without TLS. Options.Builder.build() now throws IllegalStateException when the options end up with a context, by any route, and the server list has a ws:// server. nats:// servers stay allowed because they are upgraded. Covered in OptionsTests, documented in docs/TLS_CONFIGURATION.md and the README. Also adds the permanent README note for version 2.26.5, hostname verification on by default, under Recent Version Notes, with an Important section near the top that links to it.
|
Claude finished @scottf's task in 1m 4s —— View job Review of PR #1641
SummaryCorrectness check out on Verified against existing tests: all current uses of No bugs or security issues found. The new tests in Minor, non-blocking observations:
Looks good to merge. |
…context A ws:// server is a plain websocket that is never upgraded to TLS, so a connection with an SSL context would reach it without TLS. The bootstrap list cannot hold one since the previous commit; one can still arrive in connect_urls or from a custom ServerPool. When the pool hands such a server out, both connect loops skip it before anything is sent, go on to the next server, report it through the new ErrorListener.serverRejected, and tell the pool through the new ServerPool.serverRejected. It is not a failed attempt: no exception, no connectFailed, no reconnect delay. The default pool removes the server and remembers it, so a later connect_urls does not bring it back. ErrorListener.serverRejected and ServerPool.serverRejected are default methods that do nothing; the logger and console listeners report it at WARNING. SniTestServer can send connect_urls entries as given. Tests in TLSConnectTests and ServerPoolTests.
|
@claude re-review |
|
Claude finished @scottf's task in 2m 30s —— View job Re-review of PR #1641
SummaryThe second commit adds the runtime half that the PR description originally said was out of scope — a Build-time check ( Runtime skip (
Minor, non-blocking observation: Test coverage is strong: No bugs found. Looks good to merge. |
The scheme is what made the server unusable, so the pool's rejected memory matches with NatsUri.equals, the full uri, instead of the host-and-port equivalence used for discovery dedup. A re-advertised ws:// entry parses to the same uri and is still left out; the same host and port under wss:// or nats:// stays a candidate. Pool test extended for both cases.
|
Addressed both items from the re-review, in 8228b54 and in the description.
|
…rejected server ServerPool.serverRejected is a default no-op, so a pool that implements the interface directly keeps a rejected server, and the loops had no bound against it: the rejection check runs before first is set, so a rejection ended nothing, and the only exits were first coming around or the pool running empty. Ending the loop when first is still null is not enough, since first can be set and then leave the pool through connectFailed. Each loop now maps a rejected server to the count of usable servers handed out when the pool last supplied it. The first rejection is reported and skipped. Supplied again with something usable in between, it is skipped without a report. Supplied again with nothing usable in between, the pool has nothing else the connection can use: the connect loop breaks and fails naming the server, and the reconnect loop returns and gives up as for an exhausted pool. Tests for both loops with a pool that ignores serverRejected; the pool tests share a poolWithFirst helper. Javadoc on ServerPool.serverRejected states the behavior.
|
An independent review of 8228b54 found that a custom Addressed in 390ccd1. Each loop maps a rejected server to the count of usable servers handed out when the pool last supplied it: the first rejection is reported and skipped, a repeat with something usable in between is skipped without a report, and a repeat with nothing usable in between ends the loop, so the connect fails naming the server and the reconnect gives up as for an exhausted pool. |
A connection with an SSL context requires TLS to every server, but a
ws://server is a plain websocket that is never upgraded, so it would be reached without TLS. This PR closes the three ways such a server can reach the connection.Configured in the options.
Options.Builder.build()throwsIllegalStateExceptionwhen the options end up with a context, by any route (secure,opentls, a supplied context, keystore or truststore, a context factory, or atls,wssoropentlsserver url), and the server list has aws://server. The message says to usewss://for that server.nats://servers stay allowed because they are upgraded like every other server of the connection.Advertised by the cluster in
connect_urls, or supplied by a customServerPool. When the pool hands such a server out, both connect loops skip it before anything is sent, go on to the next server, report it through the newErrorListener.serverRejected(Connection, String server, String reason), and tell the pool through the newServerPool.serverRejected(NatsUri). It is not a failed attempt: no exception, noconnectFailed, no reconnect delay. Both new methods are defaults that do nothing; the logger and console listeners report it at WARNING. The default pool removes the server and remembers its exact uri, so a laterconnect_urlsdoes not bring it back, while the same host and port under another scheme stays a candidate. A pool that keeps supplying a rejected server does not make the loops spin: when it hands one back with nothing usable handed out in between, the connect fails naming the server and the reconnect gives up as for an exhausted pool.Also in this PR: the permanent README note for version 2.26.5, hostname verification on by default (#1640), under Recent Version Notes, and an Important section near the top of the README that links to it.
Tests: nine new assertions in
OptionsTests.testSslContextIsProvidedfor the build-time rule;ServerPoolTests.testServerRejectedfor the pool;TLSConnectTests.testDiscoveredPlainWebsocketServerIsRejectedOnceandtestPlainWebsocketServerFromThePoolIsSkippedfor the runtime path end to end,testConnectEndsWhenThePoolKeepsOnlyARejectedServerandtestReconnectEndsWhenThePoolKeepsOnlyARejectedServerfor a pool that keeps a rejected server, onSniTestServer, which can now sendconnect_urlsentries as given.