Repository navigation
Add opt-in Hysteria 2 ECH profiles - #152
Conversation
📝 WalkthroughWalkthroughHysteria2 ECH support adds persisted profile fields, version 9 serialization, canonical configuration parsing, settings UI controls and validation, URI/JSON conversion, sing-box outbound generation, localized strings, and compatibility tests. ChangesHysteria2 ECH
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant HysteriaSettingsActivity
participant HysteriaBean
participant HysteriaFmt
participant SingBoxOutbound
User->>HysteriaSettingsActivity: Enable ECH and enter config
HysteriaSettingsActivity->>HysteriaFmt: Validate and canonicalize config
HysteriaSettingsActivity->>HysteriaBean: Persist ECH fields
HysteriaBean->>HysteriaFmt: Provide Hysteria2 ECH settings
HysteriaFmt->>SingBoxOutbound: Build enabled TLS ECH config
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
app/src/main/java/io/nekohasekai/sagernet/fmt/hysteria/HysteriaFmt.kt (1)
27-54: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valueNullable
echConfigvs. non-nullStringparameter.
canonicalHysteria2ECHConfig(config: String)takes a non-null KotlinString, butHysteriaBean.echConfig(Java field) is nullable. Every current call site pairsenableECH = truewith an already-validated, non-nullechConfig, so this isn't reachable today — but if a future code path setsenableECH = truedirectly on a bean without routing throughparseHysteria2/parseHysteria2Json/the validated settings-save flow,bean.echConfigcould still benull, and this call would throw a rawNullPointerException(Kotlin's intrinsic null-check) instead of the intendedIllegalArgumentExceptionwith a descriptive message.Consider accepting
String?and failing with the same descriptiveIllegalArgumentExceptionfor a null config, for a more robust contract.Also applies to: 623-628
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/src/main/java/io/nekohasekai/sagernet/fmt/hysteria/HysteriaFmt.kt` around lines 27 - 54, Update canonicalHysteria2ECHConfig to accept a nullable String and explicitly reject null with the existing descriptive IllegalArgumentException used for missing ECH configuration. Preserve the current trimming, validation, decoding, and canonicalization behavior for non-null values, including the HysteriaBean.echConfig call path.app/src/main/java/io/nekohasekai/sagernet/ui/profile/HysteriaSettingsActivity.kt (1)
49-66: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winValidation swallows the specific failure reason.
runCatching { canonicalHysteria2ECHConfig(...) }.isSuccessdiscards the exception's message, so the user always gets the same generichysteria2_ech_config_invalidtoast regardless of why the config was rejected (bad base64, incomplete PEM, malformed ECHConfigList, etc.), making it harder to fix the input.Proposed improvement to surface the failure reason
override suspend fun saveAndExit() { if (DataStore.protocolVersion == 2 && DataStore.serverHy2EchEnabled) { - val isValid = runCatching { + val result = runCatching { canonicalHysteria2ECHConfig(DataStore.serverHy2EchConfig) - }.isSuccess - if (!isValid) { + } + if (result.isFailure) { onMainDispatcher { Toast.makeText( this@HysteriaSettingsActivity, - R.string.hysteria2_ech_config_invalid, + result.exceptionOrNull()?.message ?: getString(R.string.hysteria2_ech_config_invalid), Toast.LENGTH_LONG, ).show() } return } } super.saveAndExit() }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/src/main/java/io/nekohasekai/sagernet/ui/profile/HysteriaSettingsActivity.kt` around lines 49 - 66, Update saveAndExit in HysteriaSettingsActivity to retain the exception from canonicalHysteria2ECHConfig instead of reducing validation to isSuccess. Include the captured failure reason in the invalid-configuration Toast while preserving the existing early return and successful super.saveAndExit flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@app/src/main/java/io/nekohasekai/sagernet/fmt/hysteria/HysteriaFmt.kt`:
- Around line 27-54: Update canonicalHysteria2ECHConfig to accept a nullable
String and explicitly reject null with the existing descriptive
IllegalArgumentException used for missing ECH configuration. Preserve the
current trimming, validation, decoding, and canonicalization behavior for
non-null values, including the HysteriaBean.echConfig call path.
In
`@app/src/main/java/io/nekohasekai/sagernet/ui/profile/HysteriaSettingsActivity.kt`:
- Around line 49-66: Update saveAndExit in HysteriaSettingsActivity to retain
the exception from canonicalHysteria2ECHConfig instead of reducing validation to
isSuccess. Include the captured failure reason in the invalid-configuration
Toast while preserving the existing early return and successful
super.saveAndExit flow.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d44190c0-acec-48c7-8efd-7828d2c5834b
📒 Files selected for processing (11)
app/src/main/java/io/nekohasekai/sagernet/Constants.ktapp/src/main/java/io/nekohasekai/sagernet/database/DataStore.ktapp/src/main/java/io/nekohasekai/sagernet/fmt/hysteria/HysteriaBean.javaapp/src/main/java/io/nekohasekai/sagernet/fmt/hysteria/HysteriaFmt.ktapp/src/main/java/io/nekohasekai/sagernet/ui/profile/HysteriaSettingsActivity.ktapp/src/main/res/values-zh-rCN/strings.xmlapp/src/main/res/values/strings.xmlapp/src/main/res/xml/hysteria_preferences.xmlapp/src/test/java/io/nekohasekai/sagernet/fmt/ConfigBuilderGoldenTest.ktapp/src/test/java/io/nekohasekai/sagernet/fmt/HysteriaBeanSerializationTest.ktapp/src/test/java/io/nekohasekai/sagernet/fmt/HysteriaFmtTest.kt
|
Validation completed:
The temporary validation profiles were removed after the checks. |
Summary
tls.echJSON field andechURI parameterECH CONFIGSPEM input to the static PEM form expected by sing-boxValidation
29260118847: all jobs passedGreptile Summary
This PR adds opt-in ECH support for Hysteria 2 profiles. The main changes are:
Confidence Score: 5/5
This looks safe to merge.
Important Files Changed
Reviews (3): Last reviewed commit: "fix(hysteria): validate missing ECH payl..." | Re-trigger Greptile