Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 95 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
description: Platform checks to run
type: choice
default: all
options: [all, desktop, android, apple]
options: [all, desktop, android, apple, ohos]
permissions:
contents: read
concurrency:
Expand Down Expand Up @@ -88,3 +88,97 @@ jobs:
flutter build ios --release --no-codesign
flutter build ios --simulator --debug
flutter build macos --debug

ohos:
if: github.event_name != 'workflow_dispatch' || inputs.platform == 'all' || inputs.platform == 'ohos'
runs-on: ubuntu-24.04
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: dart-lang/setup-dart@v1
- run: sudo apt-get update && sudo apt-get install -y cmake ninja-build git python3
- uses: ErBWs/setup-ohos@3a251d7e29546c19a9f5fbd3aa4614f6df196910
with:
version: 26.0.0.821
cache: true
- run: dart pub get
- run: dart test test/ohos_build_test.dart test/prebuilt_test.dart -r expanded
- name: Cross-compile using the Flutter-OH compatibility protocol
shell: bash
run: |
for arch in arm64 x64; do
dart run tool/check_native_build.dart ohos "$arch"
done
- name: Collect native libraries and hook manifests
shell: bash
run: |
python3 - <<'PY'
import json
from pathlib import Path
import re
import shutil
import struct
import subprocess
for arch in ('arm64', 'x64'):
manifest = Path(f'.dart_tool/verify/ohos-{arch}-device/output.json')
data = json.loads(manifest.read_text())
assert data['status'] == 'success'
assets = [a['encoding'] for a in data['assets']]
library = next(a['file'] for a in assets if a['id'] == 'package:ech_http/ech_http_bindings')
elf = Path(library).read_bytes()
assert elf[:6] == b'\x7fELF\x02\x01'
assert struct.unpack_from('<H', elf, 18)[0] == {'arm64': 183, 'x64': 62}[arch]
config = json.loads(manifest.with_name('input.json').read_text())
compiler = Path(config['config']['extensions']['code_assets']['c_compiler']['cc'])
dynamic = subprocess.check_output([str(compiler.parent / 'llvm-readelf'), '--dynamic', library], text=True)
needed = re.findall(r'\(NEEDED\).*?\[(.*?)\]', dynamic)
assert needed and all(name == 'libc.so' for name in needed), needed
destination = Path('build/ohos-native-assets') / arch
destination.mkdir(parents=True, exist_ok=True)
shutil.copyfile(library, destination / 'libech_http.so')
shutil.copyfile(manifest, destination / 'output.json')
PY
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '17'
- name: Set up the verified Flutter-OH toolchain
shell: bash
run: |
echo "ECH_HTTP_DART=$(command -v dart)" >> "$GITHUB_ENV"
git init "$RUNNER_TEMP/flutter-ohos"
git -C "$RUNNER_TEMP/flutter-ohos" remote add origin https://gitcode.com/CPF-Flutter/flutter_flutter.git
git -C "$RUNNER_TEMP/flutter-ohos" fetch --depth=1 origin 62357a93d653bf844f730bb1f4b7cc9e2139d14e
git -C "$RUNNER_TEMP/flutter-ohos" checkout --detach FETCH_HEAD
echo "$RUNNER_TEMP/flutter-ohos/bin" >> "$GITHUB_PATH"
echo "CI=true" >> "$GITHUB_ENV"
# Keep the package's hook kernel on the SDK that compiled it. The
# consumer below has a separate .dart_tool and uses Flutter-OH's Dart.
- run: '"$ECH_HTTP_DART" run tool/create_flutter_smoke.dart ohos'
- name: Build a Flutter consumer HAP with the native assets
working-directory: build/flutter_smoke
run: |
flutter pub get
flutter build hap --release --no-codesign
- name: Verify the HAP contains the native library and asset mapping
shell: bash
run: |
python3 - <<'PY'
import json
from pathlib import Path
from zipfile import ZipFile
haps = list(Path('build/flutter_smoke/build/ohos/hap').glob('*.hap'))
assert haps, 'No HAP was produced'
for path in haps:
with ZipFile(path) as hap:
assert 'libs/arm64-v8a/libech_http.so' in hap.namelist()
manifest = json.loads(hap.read('resources/rawfile/flutter_assets/NativeAssetsManifest.json'))
asset = manifest['native-assets']['ohos_arm64']['package:ech_http/ech_http_bindings']
assert asset == ['absolute', 'libech_http.so'], asset
PY
- uses: actions/upload-artifact@v4
with:
name: ohos-native-assets
path: |
build/ohos-native-assets/
build/flutter_smoke/build/ohos/hap/*.hap
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ coverage/
pubspec.lock
*.jpg
*.log
__pycache__/
1 change: 1 addition & 0 deletions .pubignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ coverage/
pubspec.lock
*.jpg
*.log
__pycache__/
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

---

## [Unreleased]

### Added
- OpenHarmony / HarmonyOS arm64 and x64 support through Flutter-OH Native Assets
and precompiled dependency SDKs.

### Changed
- Allow compatible `code_assets` and `hooks` versions for Flutter-OH's `meta` pin.

### Fixed
- Reset bridge CMake metadata when the package moves between checkouts or caches.

---

## [0.2.1] - 2026-09-29

### Changed
Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![Dart SDK](https://img.shields.io/badge/Dart-3.10+-0175C2.svg?logo=dart)](https://dart.dev)
[![Flutter](https://img.shields.io/badge/Flutter-3.38+-02569B.svg?logo=flutter)](https://flutter.dev)
[![Platforms](https://img.shields.io/badge/Platforms-Android%20%7C%20iOS%20%7C%20macOS%20%7C%20Linux%20%7C%20Windows-blue.svg)](#supported-platforms-and-toolchain)
[![Platforms](https://img.shields.io/badge/Platforms-Android%20%7C%20iOS%20%7C%20macOS%20%7C%20Linux%20%7C%20Windows%20%7C%20OHOS-blue.svg)](#supported-platforms-and-toolchain)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![ECH Standard](https://img.shields.io/badge/TLS%201.3-ECH%20(RFC%20Draft)-green.svg)](https://datatracker.ietf.org/doc/draft-ietf-tls-esni/)

Expand Down Expand Up @@ -34,7 +34,7 @@ flowchart TD

subgraph BuildSystem["Dart Build Hook (Build Time)"]
Hook["hook/build.dart"] -->|"Verify SHA-256"| SDKCache["Precompiled SDK Cache\n(.dart_tool or user_defines)"]
SDKCache -->|"Fetch Target Only"| PrebuiltRepo["GitHub Releases\n(Windows / Linux / Apple / Android)"]
SDKCache -->|"Fetch Target Only"| PrebuiltRepo["GitHub Releases\n(Windows / Linux / Apple / Android / OHOS)"]
Hook -->|"Compile C++ Bridge Only"| CMakeNinja["CMake + Ninja"]
CMakeNinja -->|"Bundle Native Library"| OutputLib["ech_http.dll / .so / .dylib"]
end
Expand Down Expand Up @@ -73,9 +73,13 @@ prompt cleanup.
| **macOS** | `x64`, `arm64` | macOS host, Xcode Command Line Tools, CMake, Ninja | macOS 10.15+ (x64) / 11.0+ (arm64) |
| **iOS** | `arm64` (device), `arm64`/`x64` (simulator) | macOS host, Xcode, CMake, Ninja | iOS 13.0+ |
| **Android** | `arm64-v8a`, `armeabi-v7a`, `x86_64`, `x86` | Android NDK r28.2+ (or Flutter bundled NDK), CMake, Ninja | Android API level 21+ (5.0 Lollipop) |
| **OpenHarmony / HarmonyOS** | `arm64`, `x64` | OHOS native SDK, CMake, Ninja; Flutter-OH with Native Assets support | API 26 (verified) |

For OHOS HAP builds, the hook locates the native SDK from the compiler path.
Set `OHOS_NDK_HOME` to the native SDK directory if needed.

> [!NOTE]
> Web (Browsers) and native HarmonyOS are not currently supported. Android binaries link against static libc++ and use 16 KiB ELF segment alignment for Android 15 compatibility.
> Web (Browsers) is not currently supported. Android binaries link against static libc++ and use 16 KiB ELF segment alignment for Android 15 compatibility.

---

Expand Down
10 changes: 7 additions & 3 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![Dart SDK](https://img.shields.io/badge/Dart-3.10+-0175C2.svg?logo=dart)](https://dart.dev)
[![Flutter](https://img.shields.io/badge/Flutter-3.38+-02569B.svg?logo=flutter)](https://flutter.dev)
[![Platforms](https://img.shields.io/badge/平台支持-Android%20%7C%20iOS%20%7C%20macOS%20%7C%20Linux%20%7C%20Windows-blue.svg)](#支持平台与工具链)
[![Platforms](https://img.shields.io/badge/平台支持-Android%20%7C%20iOS%20%7C%20macOS%20%7C%20Linux%20%7C%20Windows%20%7C%20OHOS-blue.svg)](#支持平台与工具链)
[![License: MIT](https://img.shields.io/badge/开源协议-MIT-yellow.svg)](LICENSE)
[![ECH Standard](https://img.shields.io/badge/TLS%201.3-ECH%20(RFC%20Draft)-green.svg)](https://datatracker.ietf.org/doc/draft-ietf-tls-esni/)

Expand Down Expand Up @@ -34,7 +34,7 @@ flowchart TD

subgraph BuildSystem["Dart Build Hook (构建期)"]
Hook["hook/build.dart 构建钩子"] -->|"校验 SHA-256 摘要"| SDKCache["预编译 SDK 本地缓存\n(.dart_tool 或 user_defines)"]
SDKCache -->|"仅下载当前构建目标"| PrebuiltRepo["GitHub Releases\n(Windows / Linux / Apple / Android)"]
SDKCache -->|"仅下载当前构建目标"| PrebuiltRepo["GitHub Releases\n(Windows / Linux / Apple / Android / OHOS)"]
Hook -->|"仅就地编译 C++ 桥接代码"| CMakeNinja["CMake + Ninja"]
CMakeNinja -->|"打包原生动态库"| OutputLib["ech_http.dll / .so / .dylib"]
end
Expand Down Expand Up @@ -70,9 +70,13 @@ flowchart TD
| **macOS** | `x64`, `arm64` | macOS 系统, Xcode Command Line Tools, CMake, Ninja | macOS 10.15+ (x64) / 11.0+ (arm64) |
| **iOS** | `arm64` (真机), `arm64`/`x64` (模拟器) | macOS 系统, Xcode, CMake, Ninja | iOS 13.0+ |
| **Android** | `arm64-v8a`, `armeabi-v7a`, `x86_64`, `x86` | Android NDK r28.2+ (或 Flutter 自带 NDK), CMake, Ninja | Android API Level 21+ (5.0 Lollipop) |
| **OpenHarmony / HarmonyOS** | `arm64`, `x64` | OHOS native SDK、CMake、Ninja;支持 Native Assets 的 Flutter-OH | API 26(已验证) |

构建 OHOS HAP 时,钩子从编译器路径定位 native SDK;需要时可通过
`OHOS_NDK_HOME` 指定 native SDK 目录。

> [!NOTE]
> 当前暂不支持浏览器 Web 环境及原生鸿蒙(HarmonyOS)。Android 原生库使用静态 libc++ 链接,并满足 Android 15 强制要求的 16 KiB ELF 页面对齐。
> 当前暂不支持浏览器 Web 环境。Android 原生库使用静态 libc++ 链接,并满足 Android 15 强制要求的 16 KiB ELF 页面对齐。

---

Expand Down
1 change: 1 addition & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ include: package:lints/recommended.yaml
analyzer:
exclude:
- .dart_tool/**
- build/**
8 changes: 5 additions & 3 deletions doc/releasing.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,21 +91,22 @@ Set `ECH_PROXY`, `ECH_CONFIG_DOMAIN`, or `ECH_ADDRESSES` in your environment to

## 3. Precompiled Dependency SDK Maintenance

`ech_http` pins versioned precompiled SDKs for 14 target architectures across four public build repositories:
`ech_http` pins versioned precompiled SDKs for 16 target architectures across five public build repositories:

- [libechhttp-win32-build](https://github.com/ech-research/libechhttp-win32-build/releases) (Windows: x64, arm64, ia32)
- [libechhttp-darwin-build](https://github.com/ech-research/libechhttp-darwin-build/releases) (macOS / iOS: x64, arm64)
- [libechhttp-android-build](https://github.com/ech-research/libechhttp-android-build/releases) (Android: arm64-v8a, armeabi-v7a, x86_64, x86)
- [libechhttp-linux-build](https://github.com/ech-research/libechhttp-linux-build/releases) (Linux: x64, arm64)
- [libechhttp-ohos-build](https://github.com/ech-research/libechhttp-ohos-build/releases) (OpenHarmony / HarmonyOS: arm64, x64)

### Upgrading Precompiled SDKs

When dependency versions (such as libcurl or BoringSSL) or compiler flags change:

1. Trigger and publish new GitHub Releases in the four platform build repositories.
1. Trigger and publish new GitHub Releases in the relevant platform build repositories.
2. In the `ech_http` repository, run the maintainer automation tool with the new release tags:
```sh
python tool/update_prebuilt.py win32=v0.1.1 darwin=v0.1.2 android=v0.1.1 linux=v0.1.1
python tool/update_prebuilt.py win32=v0.1.1 darwin=v0.1.2 android=v0.1.1 linux=v0.1.1 ohos=v0.1.0
```
*(Requires Python 3.9+ and an authenticated GitHub CLI `gh`)*.
3. Review the modified pins and SHA-256 digests in `lib/src/build_support/dependencies.json`.
Expand Down Expand Up @@ -140,6 +141,7 @@ The repository includes a GitHub Actions CI workflow (`.github/workflows/ci.yml`
- macOS desktop runners (Intel x64 and Apple Silicon arm64)
- Android APK packaging (Flutter build across arm64, arm, x64, x86)
- iOS build targets (bridge build and Flutter release build with `--no-codesign`)
- OHOS bridge builds (arm64/x64) and unsigned Flutter Release HAP packaging

Run or verify the CI pipeline before publishing. See [doc/verification.md](verification.md) for detailed verification coverage.

Expand Down
8 changes: 5 additions & 3 deletions doc/releasing.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,21 +91,22 @@ dart run example/ech_http_example.dart https://crypto.cloudflare.com/cdn-cgi/tra

## 3. 预编译原生 SDK 的更新与维护

`ech_http` 依赖 4 个独立的公开构建仓库为 14 个目标平台与架构打包发布预编译 SDK:
`ech_http` 依赖 5 个独立的公开构建仓库为 16 个目标平台与架构打包发布预编译 SDK:

- [libechhttp-win32-build](https://github.com/ech-research/libechhttp-win32-build/releases)(Windows: x64, arm64, ia32)
- [libechhttp-darwin-build](https://github.com/ech-research/libechhttp-darwin-build/releases)(macOS / iOS: x64, arm64)
- [libechhttp-android-build](https://github.com/ech-research/libechhttp-android-build/releases)(Android: arm64-v8a, armeabi-v7a, x86_64, x86)
- [libechhttp-linux-build](https://github.com/ech-research/libechhttp-linux-build/releases)(Linux: x64, arm64)
- [libechhttp-ohos-build](https://github.com/ech-research/libechhttp-ohos-build/releases)(OpenHarmony / HarmonyOS: arm64, x64)

### 升级预编译依赖版本

当 libcurl、BoringSSL 源码更新或编译参数调整时:

1. 在上述 4 个构建仓库中触发 GitHub Actions 并发布新的 Release 版本。
1. 在相应平台的构建仓库中触发 GitHub Actions 并发布新的 Release 版本。
2. 在本项目根目录下运行维护脚本,填入经过评审的新 Release 标签:
```sh
python tool/update_prebuilt.py win32=v0.1.1 darwin=v0.1.2 android=v0.1.1 linux=v0.1.1
python tool/update_prebuilt.py win32=v0.1.1 darwin=v0.1.2 android=v0.1.1 linux=v0.1.1 ohos=v0.1.0
```
*(要求本地装有 Python 3.9+ 且具备经过身份授权的 GitHub CLI `gh`)*。
3. 检查并核对 `lib/src/build_support/dependencies.json` 中自动更新的下载链接与 SHA-256 散列值。
Expand Down Expand Up @@ -140,6 +141,7 @@ dart run example/ech_http_example.dart https://crypto.cloudflare.com/cdn-cgi/tra
- macOS 环境(Intel x64 与 Apple Silicon arm64 构建及测试)
- Android 构建(Flutter 打包 arm64、arm、x64、x86 APK)
- iOS 构建(C++ 桥接编译及 Flutter `--no-codesign` 打包)
- OHOS 构建(arm64/x64 桥接编译及 Flutter 未签名 Release HAP 打包)

发布新版本前,确保 CI 所有任务绿灯通过。具体覆盖范围详见 [doc/verification.zh-CN.md](verification.zh-CN.md)。

Expand Down
6 changes: 4 additions & 2 deletions doc/verification.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,22 @@ We distinguish between three tiers of verification:
| **Android** | `arm64-v8a` | **Tier 1** | Physical device run (API 35), live ECH handshake, authenticated retry, connection reuse | Non-standard custom Android ROMs |
| **Android** | `armeabi-v7a`, `x86_64` | **Tier 2** | Flutter Debug APK packaging for both ABIs | Runtime execution on physical 32-bit ARM / x86_64 devices |
| **Android** | `x86` | **Tier 2** | NDK bridge build and link check in CI | 32-bit x86 Android runtime execution |
| **Web / HarmonyOS** | All | **Tier 3** | Not supported by this native C++ FFI architecture | N/A |
| **OpenHarmony / HarmonyOS** | `arm64`, `x64` | **Tier 2** | Precompiled SDK builds; signed Debug HAP on MatePad mini (API 26): native loading, HTTP 200 and accepted ECH | Signed Release HAP, x64 devices, lower APIs, and proxy/gzip/cancellation/isolate device regressions unverified |
| **Web** | All | **Tier 3** | Not supported by this native C++ FFI architecture | N/A |

---

## 2. Precompiled SDK Release Registry

Precompiled dependency SDKs (statically built libcurl 8.22.0 + BoringSSL + zlib 1.3.2) are hosted in four dedicated public repositories:
Precompiled dependency SDKs (statically built libcurl 8.22.0 + BoringSSL + zlib 1.3.2) are hosted in five dedicated public repositories:

| Build Repository | Release Tag | Target Platforms & Architectures |
| :--- | :--- | :--- |
| [libechhttp-win32-build](https://github.com/ech-research/libechhttp-win32-build) | `v0.1.1` | Windows: `x64`, `arm64`, `ia32` |
| [libechhttp-darwin-build](https://github.com/ech-research/libechhttp-darwin-build) | `v0.1.2` | macOS / iOS: `x64`, `arm64` (Device + Simulator) |
| [libechhttp-android-build](https://github.com/ech-research/libechhttp-android-build) | `v0.1.1` | Android: `arm64-v8a`, `armeabi-v7a`, `x86_64`, `x86` |
| [libechhttp-linux-build](https://github.com/ech-research/libechhttp-linux-build) | `v0.1.1` | Linux: `x64`, `arm64` |
| [libechhttp-ohos-build](https://github.com/ech-research/libechhttp-ohos-build) | `v0.1.0` | OpenHarmony / HarmonyOS: `arm64`, `x64` (SDK API 26) |

All release archives and their SHA-256 digests are pinned in [lib/src/build_support/dependencies.json](../lib/src/build_support/dependencies.json).

Expand Down
6 changes: 4 additions & 2 deletions doc/verification.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,22 @@ Flutter Android APK、iOS 未签名 Release 应用、iOS 模拟器 Debug 应用
| **Android** | `arm64-v8a` | **Tier 1** | 真实设备运行(API 35),公网 ECH 握手、认证重试、连接复用均通过 | 各类深度定制的非标准第三方 Android ROM |
| **Android** | `armeabi-v7a`, `x86_64` | **Tier 2** | Flutter Debug APK 多 ABI 打包测试通过 | 32 位 ARM / x86_64 物理机运行时执行 |
| **Android** | `x86` | **Tier 2** | CI 中 NDK 桥接构建与链接核验通过 | 32 位 x86 Android 实体机运行时执行 |
| **Web / 原生鸿蒙** | 全部架构 | **Tier 3** | C++ FFI 原生引擎架构暂不支持 Web 与 HarmonyOS | 不适用 |
| **OpenHarmony / HarmonyOS** | `arm64`, `x64` | **Tier 2** | 预编译 SDK 构建;MatePad mini(API 26)签名 Debug HAP 原生库加载、HTTP 200 和 ECH 通过 | 未验证签名 Release HAP、x64 真机、低 API 及代理/gzip/取消请求/isolate 退出的真机回归 |
| **Web** | 全部架构 | **Tier 3** | C++ FFI 原生引擎架构不支持 Web | 不适用 |

---

## 2. 预编译 SDK 仓库索引

预编译依赖库(静态构建的 libcurl 8.22.0、BoringSSL 与 zlib 1.3.2)托管在四个独立的公开构建仓库中:
预编译依赖库(静态构建的 libcurl 8.22.0、BoringSSL 与 zlib 1.3.2)托管在五个独立的公开构建仓库中:

| 构建仓库 | 发布 Tag | 支持的目标平台与架构 |
| :--- | :--- | :--- |
| [libechhttp-win32-build](https://github.com/ech-research/libechhttp-win32-build) | `v0.1.1` | Windows: `x64`, `arm64`, `ia32` |
| [libechhttp-darwin-build](https://github.com/ech-research/libechhttp-darwin-build) | `v0.1.2` | macOS / iOS: `x64`, `arm64`(真机 + 模拟器) |
| [libechhttp-android-build](https://github.com/ech-research/libechhttp-android-build) | `v0.1.1` | Android: `arm64-v8a`, `armeabi-v7a`, `x86_64`, `x86` |
| [libechhttp-linux-build](https://github.com/ech-research/libechhttp-linux-build) | `v0.1.1` | Linux: `x64`, `arm64` |
| [libechhttp-ohos-build](https://github.com/ech-research/libechhttp-ohos-build) | `v0.1.0` | OpenHarmony / HarmonyOS: `arm64`, `x64` (SDK API 26) |

每个 SDK 压缩包的 SHA-256 散列均固化在 [lib/src/build_support/dependencies.json](../lib/src/build_support/dependencies.json) 中。

Expand Down
Loading
Loading