Skip to content

feat(ohttp): wasm derives OHTTP outer scheme from fetch URL + TLS/plain integration tests#171

Merged
imlk0 merged 1 commit into
masterfrom
wasm-ohttp-scheme
Jul 15, 2026
Merged

feat(ohttp): wasm derives OHTTP outer scheme from fetch URL + TLS/plain integration tests#171
imlk0 merged 1 commit into
masterfrom
wasm-ohttp-scheme

Conversation

@imlk0

@imlk0 imlk0 commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

Summary

On wasm builds the JS SDK is OHTTP-only and has no ohttp.tls config field (the browser performs TLS). Instead of a config flag, the wasm ingress derives the outer OHTTP POST scheme from the scheme of the URL passed to the wasm fetch(url, init, config) interface: https => https (browser TLS), anything else => http. Native ingress is unchanged.

Changes

  • cfg-gate tls / tls_ca_certs off on wasm (OHttpArgs). The struct is #[serde(deny_unknown_fields)], so providing either field in a wasm config is now a parse error (fail-fast). Native keeps both and drives reqwest TLS + CA trust from them.
  • OHttpSecurityLayer::scheme_from_url(Option<&str>) -> &'static str (cfg-agnostic pub fn) returning a &'static str literal — no allocation, survives the URI move in dispatch_request. scheme_from_tls becomes #[cfg(not(wasm))].
  • OHttpSecurityLayer::new gains a #[cfg(wasm)] url_scheme: &'static str param (plain // comment, not /// — doc comments are illegal on fn params and broke the wasm build, which the native build masked). dispatch_request normalizes the scheme via scheme_from_url before build_http_request moves request_uri.
  • Docs (EN + ZH): docs/configuration{,_zh}.md (wasm has no tls/tls_ca_certs; scheme mirrors the fetch URL), docs/developer{,_zh}.md (list the new test).

Integration tests

tng-testsuite/tests/ohttp/ohttp_tls_wasm.rs (required-features = ["js-sdk"]):

  • test_ohttps_forwarded_over_tls_wasm — https POST to a TlsTcpProxy gateway (self-signed) → TLS termination → egress mapping-in → OHTTP decap → HttpServer.
  • test_ohttp_forwarded_plain_wasm — http POST direct to the egress mapping-in → OHTTP decap → HttpServer.

Supporting:

  • browser_client.rs: add --ignore-certificate-errors so headless Chrome accepts the self-signed gateway cert (--disable-web-security only bypasses CORS, not certificate validation); a no-op for the existing http-only tests.
  • The wasm fetch path mandates a real attestation result (forward_request bails on None), so no_ra is not usable through wasm; the tests mirror js_sdk_http.rs (egress attest via AA, wasm ingress verify against AS). Prerequisite: make wasm-build-debug for the pre-built tng-wasm/pkg.

Verification

  • cargo test -p tng-testsuite --test ohttp_tls_wasm --features js-sdk => 2 passed
  • cargo test -p tng-testsuite --test js_sdk_http --features js-sdk (regression for the new Chrome cap) => 2 passed
  • make wasm-build-debug => EXIT 0 (tng-wasm/pkg regenerated)
  • cargo fmt / cargo clippy -p tng-testsuite --tests --features js-sdk => clean

Backward compatibility

Additive for existing native configs (they keep tls/tls_ca_certs and behave unchanged). The only breakage is on wasm configs that previously set tls/tls_ca_certs — which were never effective on wasm anyway (the browser always controls TLS); now they fail fast with a parse error. No version_compatibility row needed for the wasm scheme change itself; if a wasm config relied on tls, that is a new wasm-side parse error worth a compatibility note — happy to add a row if reviewers want it.

…ion tests

On wasm builds the JS SDK is OHTTP-only and has no `ohttp.tls` config field
(the browser performs TLS). Instead of a config flag, the wasm ingress derives
the outer OHTTP POST scheme from the scheme of the URL passed to the wasm
`fetch(url, init, config)` interface: `https` => `https` (browser TLS), anything
else => `http` (the pre-feature default). Native ingress is unchanged.

Implementation:
- cfg-gate the ingress `OHttpArgs.tls` and `tls_ca_certs` fields off on wasm.
  The struct is `#[serde(deny_unknown_fields)]`, so providing either in a wasm
  config is now a parse error (fail-fast). Native keeps both fields and drives
  reqwest TLS + CA trust from them.
- Add `OHttpSecurityLayer::scheme_from_url(Option<&str>) -> &'static str`
  (cfg-agnostic pub associated fn) returning a `&'static str` literal — no
  allocation, and the result does not borrow the (temporary) parsed URI, so it
  survives the URI move in `dispatch_request`. `scheme_from_tls` becomes
  `#[cfg(not(wasm))]` (native-only).
- `OHttpSecurityLayer::new` gains a `#[cfg(wasm)] url_scheme: &'static str`
  param (plain `//` comment, not `///` — doc comments are illegal on fn params
  and broke the wasm build). `tng-wasm/src/fetch/mod.rs::dispatch_request`
  normalizes the scheme via `scheme_from_url` BEFORE `build_http_request` moves
  `request_uri`, then threads it through `forward_request` into `new`.

Docs:
- `docs/configuration{,_zh}.md`: on wasm neither `tls` nor `tls_ca_certs`
  exists; the outer OHTTP POST scheme mirrors the fetch URL's scheme.
- `docs/developer{,_zh}.md`: list the new `ohttp_tls_wasm` integration test.

Integration tests (`tng-testsuite/tests/ohttp/ohttp_tls_wasm.rs`,
`required-features = ["js-sdk"]`):
- test_ohttps_forwarded_over_tls_wasm: https POST to a TlsTcpProxy gateway
  (self-signed) -> TLS termination -> egress mapping-in -> OHTTP decap ->
  HttpServer.
- test_ohttp_forwarded_plain_wasm: http POST direct to the egress mapping-in.
- `browser_client.rs`: add `--ignore-certificate-errors` so headless Chrome
  accepts the self-signed gateway cert (`--disable-web-security` only bypasses
  CORS, not certificate validation); a no-op for the existing http-only tests.
- The wasm fetch path mandates a real attestation result (`forward_request`
  bails on None), so `no_ra` is not usable through wasm; the tests mirror
  `js_sdk_http.rs` (egress `attest` via AA, wasm ingress `verify` against AS).
  Prerequisite: `make wasm-build-debug` for the pre-built `tng-wasm/pkg`.

Verified: `cargo test -p tng-testsuite --test ohttp_tls_wasm --features js-sdk`
=> 2 passed; `js_sdk_http` regression => 2 passed; `make wasm-build-debug`
=> EXIT 0; `cargo fmt` / `cargo clippy` clean.

Assisted-by: Claude:glm-5.2
@shankailun-aliyun

Copy link
Copy Markdown
Collaborator

@imlk0 ,您好,您的请求已接收,请耐心等待结果。

@shankailun-aliyun

Copy link
Copy Markdown
Collaborator

@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start

@codecov

codecov Bot commented Jul 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.23810% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
.../src/tunnel/ingress/protocol/ohttp/security/mod.rs 95.23% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@imlk0
imlk0 merged commit 29ec690 into master Jul 15, 2026
33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants