[release] Remove HxProxyConfig from lib-httpx in favour of lib-util-net ProxyConfig (2.7.0) - #123
Conversation
18a1237 to
57fbb37
Compare
57fbb37 to
c947ddf
Compare
|
This removes Stacked on #122 (already approved); its base retargets to @claude review |
|
Claude finished @pditommaso's task in 2m 24s —— View job Review: remove
|
| behaviour | parity |
|---|---|
toProxySelector() — precomputed lists, scheme routing, connectFailed logging |
identical |
toAuthenticator() — RequestorType.PROXY guard, host+port match, empty-password fallback |
identical |
isBypassed() — loopback set, *, *.x / .x suffix-only, bare x = host + subdomains |
identical, character for character |
credentialsFor() — https endpoint preferred, case-insensitive host |
identical |
hasCredentials() |
identical |
The withProxyConfig body (HxClient.java:1247-1256) is unchanged and still typechecks: getHttpProxy()/getHttpsProxy() return ProxyConfig.Endpoint instead of the package-private ProxyEntry, and the body only null-checks them. api project(':lib-util-net') (not implementation) is the right scope, since ProxyConfig is in the public signature of withProxyConfig.
Test coverage is not lost: every scenario in the deleted HxProxyConfigTest (scheme selection, direct-connect fallback, NO_PROXY matching, wildcard, loopback, authenticator scoping, no-credentials → null authenticator) has an equivalent in lib-util-net's ProxyConfigTest, which additionally covers parsing, credential decoding, and the CONNECT-tunnel case. HxClientProxyAuthIntegrationTest still exercises a real HxClient end-to-end through the authenticating proxy.
Blocking-ish for the release: lib-httpx/README.md is stale
CLAUDE.md says "When releasing a new version, update the module's README.md to reflect the new version number" — and beyond the version, the README still documents the class this PR deletes. A user copy-pasting from it gets code that does not compile:
lib-httpx/README.md:13—implementation 'io.seqera:lib-httpx:2.6.0'→2.7.0lib-httpx/README.md:28— feature bullet still says "anHxProxyConfigvalue"lib-httpx/README.md:407-418— the whole proxy example usesHxProxyConfig.newBuilder().httpsProxy(host, port, user, pass).noProxy(...), an API that no longer existslib-httpx/README.md:472— Key Classes still listsHxProxyConfig: "assembled from explicit values via its builder"
Worth also noting in the README that the type now comes from io.seqera:lib-util-net, since it is an api dependency callers will see on their compile classpath.
Non-blocking notes
1. Point the migration at the 4-arg fromUri for raw credentials. The PR body and changelog suggest:
ProxyConfig.fromUri("http://user:pass@host:port")That embeds credentials in a URI, so a password containing @, : or % has to be percent-encoded by the caller or it mis-parses silently — a footgun the old httpProxy(host, port, user, pass) builder didn't have. ProxyConfig already has the safe overload:
ProxyConfig.fromUri("http://host:port", user, pass, noProxy); // explicit creds win over user-infoCalling that out in changelog.txt (and the README) would spare migrating callers a subtle bug. The integration test's "http://alice:s3cret@127.0.0.1:${proxyPort}" is fine as-is since those credentials are literal-safe.
2. Small semantic shift worth a changelog line. HxProxyConfig could carry an http proxy without an https one (and vice versa); ProxyConfig.fromUri always applies one endpoint to both. Asymmetric per-protocol config is now only reachable via fromEnvironment. Not a bug for any current caller — just no longer expressible from explicit values.
3. Publish ordering (informational). .github/workflows/build.yml publishes lib-httpx (line 88) before lib-util-net (line 97). Harmless here — #122 lands first, and even in a shared run both artifacts appear before the job ends — but if the two ever released together, lib-httpx's POM would briefly reference a coordinate not yet in S3.
What I could not verify
I couldn't run ./gradlew :lib-httpx:test — the build command needed approval in this sandbox, so the green test run reported in the PR body is unverified by me. The compile-level reasoning above is from reading the sources.
· branch claude/lib-httpx-drop-hxproxyconfig
c947ddf to
2cd40af
Compare
|
Addressed the doc/changelog items:
On the verdict: agreed the breaking-change-as-a-minor is a maintainer call, not the bot's — leaving the approval/merge decision to @pditommaso. |
…(lib-httpx 2.7.0) BREAKING (shipped as a minor - see changelog): delete HxProxyConfig and depend on io.seqera:lib-util-net so the proxy selector / authenticator / no-proxy semantics live in one place, shared with Wave and Nextflow instead of being duplicated across lib-httpx and lib-util-net. HxClient.Builder.withProxyConfig now accepts an io.seqera.util.net.ProxyConfig (its toProxySelector()/toAuthenticator()/getHttpProxy()/getHttpsProxy() are the same shape the method already used). Callers that built an HxProxyConfig resolve a ProxyConfig instead via ProxyConfig.fromUri(...)/fromEnvironment(...). The only affected consumer (Nextflow) is migrated in lock-step. Also updates README (version + proxy example/Key Classes now reference ProxyConfig) and reorders the publish workflow so lib-util-net is published before its new dependent lib-httpx. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2cd40af to
8615797
Compare
…0) (#122) * [release] Add ProxyConfig egress-proxy resolver to lib-util-net (0.2.0) Add io.seqera.util.net.ProxyConfig: resolve an HTTP/HTTPS forward (egress) proxy - including an authenticating one - from a proxy URI or from the HTTP_PROXY/HTTPS_PROXY/NO_PROXY environment variables, exposed as a java.net ProxySelector and a proxy-scoped Authenticator suitable for a java.net.http.HttpClient. Parsing, credential-decoding, no-proxy and Basic-over-CONNECT semantics mirror Nextflow's nextflow.util.ProxyConfig (the source of truth), so products sharing this class share the same proxy behaviour. Depends only on the JDK plus the slf4j-api logging facade; the caller passes the URI or environment map in. This lets Wave (and, subsequently, Nextflow) drop their own duplicated resolver implementations. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Make ProxyConfig.parse public for component-level reuse Expose parse(String) and the Parsed record so callers needing the individual proxy components (e.g. Nextflow's Launcher, which sets -Dhttp.proxyHost system properties) can reuse the parsing instead of duplicating it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Add ProxyConfig.setupFromEnvironment for JVM-global proxy install Capture the env->proxy setup previously hand-rolled in Nextflow's launcher: set per-protocol http/https/ftp proxyHost/proxyPort + http.nonProxyHosts system properties, install the proxy-scoped Authenticator as the JVM default and clear jdk.http.auth.tunneling.disabledSchemes when credentials are present. Returns the resolved http/https ProxyConfig for wiring java.net.http clients explicitly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Expose resolved proxy endpoints on ProxyConfig Make the Endpoint record public and add getHttpProxy()/getHttpsProxy()/ getNoProxyHosts() so a caller (e.g. Nextflow) can adapt the resolved config to another representation such as lib-httpx HxProxyConfig without re-parsing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Add setupFromEnvironment coverage: ALL_PROXY fallback and disabledSchemes cases Recapture the behaviours previously verified in Nextflow's LauncherTest (now that the setup logic lives here): ALL_PROXY fallback for the per-protocol system properties, and the jdk.http.auth.tunneling.disabledSchemes clear/preserve rules. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Address review: lenient env parsing, username-only creds, null-safety, redaction - fromEnvironment tolerates an unsupported scheme (e.g. socks5://) or malformed value, logging and treating it as absent instead of throwing; fromUri still throws - parse keeps a username-only user-info (e.g. a token proxy) instead of dropping it - fromEnvironment/setupFromEnvironment return null for a null env map - warn when a proxy is addressed over https (JDK has no TLS-to-proxy support) - Parsed.toString redacts the password - README: move the egress-proxy section under Usage (was nested under Limitations) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Address re-review: redact proxy creds in errors, fix NO_PROXY->nonProxyHosts B1: redact the user-info before logging/raising an invalid proxy value, so the proxy password never reaches the log or an exception message (parseLenient + parse) B2: map NO_PROXY to the JDK http.nonProxyHosts grammar (exact host + '*' wildcard), prepend the default loopback bypass it would otherwise replace, expand a bare host to 'host|*.host' to match isBypassed, and set ftp.nonProxyHosts too N1: default the proxy port from the proxy scheme (http->80, https->443) in fromEnvironment, matching fromUri N3: make the public Endpoint record's hasCredentials()/address() public N4/N5: javadoc notes (ftp is system-property only; IPv6-without-scheme and NO_PROXY-port limits) N6: @ResourceLock the JVM-global-mutating tests Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Redact the password in Endpoint.toString (review follow-up) Endpoint is public and returned by getHttpProxy()/getHttpsProxy(), so its default record toString() would render the proxy password if a consumer logged it - the same latent leak class B1 closed for Parsed. Add a redacting toString override. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * [release] Remove HxProxyConfig in favour of lib-util-net ProxyConfig (lib-httpx 2.7.0) (#123) BREAKING (shipped as a minor - see changelog): delete HxProxyConfig and depend on io.seqera:lib-util-net so the proxy selector / authenticator / no-proxy semantics live in one place, shared with Wave and Nextflow instead of being duplicated across lib-httpx and lib-util-net. HxClient.Builder.withProxyConfig now accepts an io.seqera.util.net.ProxyConfig (its toProxySelector()/toAuthenticator()/getHttpProxy()/getHttpsProxy() are the same shape the method already used). Callers that built an HxProxyConfig resolve a ProxyConfig instead via ProxyConfig.fromUri(...)/fromEnvironment(...). The only affected consumer (Nextflow) is migrated in lock-step. Also updates README (version + proxy example/Key Classes now reference ProxyConfig) and reorders the publish workflow so lib-util-net is published before its new dependent lib-httpx. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Summary
Follow-up to #122 (which adds
io.seqera.util.net.ProxyConfigto lib-util-net). This removes the near-identical duplicate the reviewer flagged: lib-httpx now depends on lib-util-net andHxProxyConfigis deleted, so the proxy selector / authenticator / no-proxy semantics live in exactly one place, shared with Wave and Nextflow.Changes (BREAKING (shipped as a minor - see changelog) → lib-httpx 2.7.0)
HxProxyConfig(andHxProxyConfigTest) — its parsing-freeEndpoint/toProxySelector/toAuthenticator/isBypassed/credentialsForwere character-for-character identical to lib-util-net'sProxyConfig.HxClient.Builder.withProxyConfignow accepts anio.seqera.util.net.ProxyConfig. The body is unchanged — it already usedgetHttpProxy()/getHttpsProxy()/toProxySelector()/toAuthenticator(), whichProxyConfigexposes with the same shape.build.gradle:api project(':lib-util-net').HxClientProxyAuthIntegrationTestmigrated toProxyConfig(the integration test now resolves viaProxyConfig.fromUri(...)).Migration for callers
Anything that built an
HxProxyConfigresolves aProxyConfiginstead:The only in-repo/-org caller is Nextflow (
nextflow.util.ProxyConfig+TowerXAuth), migrated alongside this change; Platform and Wave don't useHxProxyConfig.Tests
:lib-httpx:testgreen, incl.HxClientProxyAuthIntegrationTest(9/9) driving a realHxClientthrough an authenticating proxy via the migratedProxyConfig.🤖 Generated with Claude Code