Measure the missing ECH call instead of describing it - #55
Merged
Conversation
Three changes that answer the same question from different sides.
**A platform that makes the call.** `EchConscryptTest` shows Conscrypt can encrypt
a client hello, but it shows it from a socket factory, with a config list the
suite kept for itself — so it never says whether the config list OkHttp resolved
would arrive. `EchConscryptPlatform` is a `Platform` that makes the one call
`ConscryptPlatform` omits, and `EchPlatformTest` runs `EchTest`'s requests
through ordinary public API with it installed. Same client, same servers, same
assertions; the difference between the two suites is one call to
`Conscrypt.setEchConfigList` and nothing else.
Upstream can't do this yet — OkHttp's master won't compile against a Conscrypt
with these methods, because no published Conscrypt has them — which is why the
platform is written here rather than waiting on #9559.
It has to import `okhttp3.internal`: a Platform is declared nowhere else. Rather
than delete the public-API rule for everybody, a file can now opt out by saying
why, and `checkPublicApiOnly` prints every exemption on every run:
// USES-OKHTTP-INTERNALS: is a Platform, which OkHttp only declares internally.
Verified without a network: after `install()`, a plain `OkHttpClient()` gets
Conscrypt's socket factory and the ECH-enabling trust manager, and `uninstall()`
puts `Jdk9Platform` back.
**Runs say what they ran on.** Each workflow records a platform — measured from
the JVM's own properties, or from the emulator's declared API level and
architecture rather than a second copy of them — and `collect_results.py` carries
it per suite rather than per version, because a version card merges an Android
artifact with a JVM one. Replaces the hardcoded `"javaVersion": "21"`, which was
neither measured nor true of the Android suite.
**The ECH page leads with results.** A matrix of server against platform, read
from `latest.json`: one row per server, one column per way of reaching it, so the
gap between "OkHttp as shipped" and "OkHttp + the missing call" is a column
comparison rather than a paragraph. Checked in a browser against synthesised
results, including the case where a suite is absent.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CqiK79k9uoWsn2AzgXpHMA
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.
Three changes that come at the same question from different sides.
A platform that makes the call
EchConscryptTestshows Conscrypt can encrypt a client hello — but from a socket factory, with a config list the suite kept for itself. It never says whether the config list OkHttp resolved would arrive.EchConscryptPlatformis aPlatformthat makes the one callConscryptPlatformomits.EchPlatformTestthen runsEchTest's requests through ordinary public API with it installed: same client, same servers, same assertions. The difference between the two suites is one call toConscrypt.setEchConfigListand nothing else, which makes the pair a measurement rather than an argument.This can't be done upstream yet — OkHttp's
masterwon't compile against a Conscrypt that has these methods, since no published Conscrypt does. That's why the platform lives here instead of waiting on lysine-dev/okhttp#9559. It is not a proposal for how OkHttp should do it:ConscryptPlatformisfinalwith a private constructor, so this reimplements the parts it needs, and upstream uses the newersetEchParametersAPI rather than thesetEchConfigListthisgoogle3-exportbuild exposes.On the public API rule. A
Platformis declared nowhere butokhttp3.internal, so this file has to import it. Rather than delete the rule for everybody, a file can opt out by saying why, andcheckPublicApiOnlyprints every exemption on every run:Verified with no network involved:
The handshake itself needs the servers, so the result arrives with the next
networkrun.Runs say what they ran on
Every workflow now records a platform, and
collect_results.pycarries it per suite rather than per version — a version card merges an Android artifact with a JVM one, so "which platform" is a property of the suite.Eclipse Adoptium JDK 21.0.8 · amd64.Android emulator API 37.0 · x86_64, from env vars the emulator step and the metadata both read, so the two can't drift.This replaces the hardcoded
"javaVersion": "21", which was neither measured nor true of the Android suite.The ECH page leads with results
site/topics/ech.htmlnow opens with a matrix built fromlatest.json: one row per server, one column per way of reaching it, platform read from the run. The gap between "OkHttp as shipped" and "OkHttp + the missing call" becomes a column comparison instead of a paragraph.Rendered in a browser against synthesised results — including a suite being absent, and Android's
[emulator-5554 - 17]case-name suffix — with no console errors.Checked
:network:compileTestKotlinagainst5.5.0-SNAPSHOT. Worth noting: the default pinned version excludes all ECH sources, so compiling without-PokhttpVersionsilently checks nothing here.collect_results.pyend to end on synthetic artifacts: platform per suite, both platforms on the card,echPlatformTestranked as a finding rather than a failure.echPlatformTestregisters on the default version too.Generated by Claude Code