Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c44e347
feat(network): recover interface bindings and NAT mappings on resume
metah3m Oct 8, 2026
d14a2d7
feat(sdk): restore Node.js and Python bindings
metah3m Oct 8, 2026
1717c15
test(endpoint): cover extended CONNECT duplex streaming
metah3m Oct 8, 2026
a42a59c
fix(network): allow optional client OCSP and pin test transport revis…
metah3m Oct 9, 2026
707ab86
fix: adapt endpoint ownership to current QUIC snapshot
metah3m Oct 9, 2026
5d56958
fix(network): filter auxiliary interfaces by platform
metah3m Oct 10, 2026
e76d4df
fix: evict unusable H3 connections and pin integrated dependencies
metah3m Oct 10, 2026
a8843d9
build: pin final validated QUIC and H3 revisions
metah3m Oct 10, 2026
a7c9fb2
chore(release): prepare dhttp v0.7.0
metah3m Oct 12, 2026
95c3063
chore(docs): keep implementation notes out of release
metah3m Oct 12, 2026
0673075
feat(network): expose active binding snapshots
metah3m Oct 12, 2026
a572174
fix(release): validate dhttp tag publication
metah3m Oct 12, 2026
3306c28
feat(home): own identity management and explicit OCSP preparation
metah3m Oct 12, 2026
279a755
ci: freeze registry dependencies and install Android SDK tools
metah3m Oct 12, 2026
21dd5df
fix(ci): preserve conversion API and keep the silent STUN test socket…
metah3m Oct 12, 2026
f16f607
fix(ci): support older Clippy versions for the frozen conversion API
metah3m Oct 12, 2026
196dadb
build: retain libc compatibility for locked iOS checks
metah3m Oct 12, 2026
05d4c39
test: respect Windows filename restrictions in identity discovery
metah3m Oct 12, 2026
f7f3710
ci: include existing language SDK tests in native coverage
metah3m Oct 12, 2026
56931ec
build: require the published Android UDP compatibility patch
metah3m Oct 12, 2026
0cda8d0
fix(ci): derive the native coverage object path from Cargo metadata
metah3m Oct 12, 2026
4c4eee2
docs: restore the English README layout and update SDK examples
metah3m Oct 12, 2026
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
31 changes: 29 additions & 2 deletions .github/workflows/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,35 @@ jobs:
sudo apt-get update
sudo apt-get install --assume-yes --no-install-recommends libpam0g-dev
- uses: taiki-e/install-action@cargo-llvm-cov
# Limit test parallelism to 1 thread to avoid resource contention
- run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info -- --test-threads=1
- uses: actions/setup-node@v4
with:
node-version: "22"
- uses: actions/setup-python@v5
with:
python-version: "3.13"
- name: Cover Rust and language SDK integration tests
shell: bash
run: |
set -euo pipefail
python -m venv "$RUNNER_TEMP/sdk-venv"
source "$RUNNER_TEMP/sdk-venv/bin/activate"
python -m pip install 'maturin>=1.8,<2'
eval "$(cargo llvm-cov show-env --export-prefix)"
cargo llvm-cov clean --workspace
cargo test --locked --all-features --workspace -- --test-threads=1
export DHTTP_TEST_OPENSSL="$(command -v openssl)"
cargo test --locked -p dhttp-api --test quic_roundtrip -- --include-ignored --test-threads=1
export DHTTP_TEST_PROFILE_ROOT="$RUNNER_TEMP/sdk-fixtures"
cargo run --locked -p dhttp-api --example sdk_credentials -- "$DHTTP_TEST_PROFILE_ROOT"
npm --prefix api run build
node --test api/tests/node.test.cjs
# Preserve the N-API coverage object before the PyO3 build replaces it.
native_target="$(cargo metadata --locked --no-deps --format-version 1 | python -c 'import json, sys; print(json.load(sys.stdin)["target_directory"])')"
native_hash="$(sha256sum "$native_target/debug/libdhttp_api.so" | cut -d ' ' -f1)"
cp "$native_target/debug/libdhttp_api.so" "$native_target/debug/deps/libdhttp_api-$native_hash.so"
maturin develop --locked --manifest-path api/Cargo.toml
python -m unittest discover -s api/tests -p test_python_sdk.py -v
cargo llvm-cov report --lcov --output-path lcov.info

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
Expand Down
93 changes: 93 additions & 0 deletions .github/workflows/network-platforms.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: Network platforms

on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
workflow_dispatch:

env:
CARGO_TERM_COLOR: always

jobs:
# The Rust workflow runs the full suite on Ubuntu, macOS and Windows.
# Exercise another GNU userspace and the static musl build used on Alpine.
debian:
runs-on: ubuntu-latest
container: rust:bookworm
steps:
- uses: actions/checkout@v4
- name: Test interface bindings and network lifecycle
run: cargo test --locked -p dhttp --lib --test network_lifecycle -- --test-threads=1

musl:
runs-on: ubuntu-latest
env:
CC_x86_64_unknown_linux_musl: musl-gcc
CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER: musl-gcc
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
target: x86_64-unknown-linux-musl
- name: Install musl compiler
run: |
sudo apt-get update
sudo apt-get install --assume-yes --no-install-recommends musl-tools
- name: Test interface bindings and network lifecycle with musl
run: cargo test --locked -p dhttp --target x86_64-unknown-linux-musl --lib --test network_lifecycle -- --test-threads=1

ios:
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
target: [aarch64-apple-ios, aarch64-apple-ios-sim, x86_64-apple-ios]
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
target: ${{ matrix.target }}
- name: Check iOS device and simulator builds
run: cargo check --locked -p dhttp --lib --target ${{ matrix.target }}

android:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- target: aarch64-linux-android
clang: aarch64-linux-android21
- target: armv7-linux-androideabi
clang: armv7a-linux-androideabi21
- target: x86_64-linux-android
clang: x86_64-linux-android21
- target: i686-linux-android
clang: i686-linux-android21
env:
ANDROID_PLATFORM: android-34
ANDROID_BUILD_TOOLS_VERSION: 34.0.0
steps:
- uses: actions/checkout@v4
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
target: ${{ matrix.target }}
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"
- name: Set up Android SDK tools
uses: android-actions/setup-android@v4
- name: Install Android Java build dependencies
run: sdkmanager "platforms;android-34" "build-tools;34.0.0"
- uses: nttld/setup-ndk@v1
id: ndk
with:
ndk-version: r27d
- name: Check Android builds
env:
TARGET_CC: ${{ steps.ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin/${{ matrix.clang }}-clang
TARGET_AR: ${{ steps.ndk.outputs.ndk-path }}/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar
run: cargo check --locked -p dhttp --lib --target ${{ matrix.target }}
102 changes: 68 additions & 34 deletions .github/workflows/publish-crates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,38 +22,43 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Validate release tag version
if: github.ref_type == 'tag' && startsWith(github.ref_name, 'v')
run: |
python3 - "$GITHUB_REF_NAME" <<'PY'
import sys
import tomllib
from pathlib import Path

manifest = tomllib.loads(Path("Cargo.toml").read_text())
package = manifest.get("package", manifest.get("workspace", {}).get("package", {}))
expected = f"v{package['version']}"
if sys.argv[1] != expected:
raise SystemExit(f"release tag {sys.argv[1]} must match {expected}")
PY

- name: Install Rust stable toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1

- name: Check formatting
run: cargo fmt -- --check

# The identity-only tag bootstraps the stable dependency graph. Other
# workspace members intentionally reference crates published later.
- name: Run clippy
if: ${{ !endsWith(github.head_ref, '-dhttp-identity') && !endsWith(github.ref_name, '-dhttp-identity') }}
run: cargo clippy --workspace --all-targets --all-features -- -D warnings

- name: Test workspace
if: ${{ !endsWith(github.head_ref, '-dhttp-identity') && !endsWith(github.ref_name, '-dhttp-identity') }}
run: cargo test --workspace --all-features --all-targets

- name: Check dhttp-identity
if: ${{ endsWith(github.head_ref, '-dhttp-identity') || endsWith(github.ref_name, '-dhttp-identity') }}
run: |
cargo clippy --package dhttp-identity --all-targets --all-features -- -D warnings
cargo test --package dhttp-identity --all-features --all-targets
run: cargo test --workspace --all-features --all-targets -- --test-threads=1

- name: Authenticate to crates.io
if: github.ref_type == 'tag' && startsWith(github.ref_name, 'v')
uses: rust-lang/crates-io-auth-action@v1
id: auth

- name: Release publishable Rust crates
- name: Release publishable workspace crates
shell: bash
env:
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
IDENTITY_ONLY: ${{ endsWith(github.head_ref, '-dhttp-identity') || endsWith(github.ref_name, '-dhttp-identity') }}
FIRST_PUBLISH_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
set -euo pipefail

Expand All @@ -63,23 +68,20 @@ jobs:
mode=dry-run
fi

if [[ "${IDENTITY_ONLY}" == "true" ]]; then
packages=(dhttp-identity)
else
packages=(
dhttp-identity
dhttp-home
dhttp-access
dhttp-log
dhttp
)
fi
# Dependencies must precede dependents for per-crate publication.
packages=(
dhttp-home
dhttp-access
dhttp-log
dhttp
)

cargo metadata --no-deps --format-version 1 > "$RUNNER_TEMP/workspace-metadata.json"
cargo metadata --format-version 1 > "$RUNNER_TEMP/workspace-metadata.json"
package_versions="$(
PACKAGES="$(printf '%s\n' "${packages[@]}")" RUNNER_TEMP="$RUNNER_TEMP" python3 - <<'PY'
import json
import os
import sys
from pathlib import Path

metadata = json.loads((Path(os.environ["RUNNER_TEMP"]) / "workspace-metadata.json").read_text())
Expand All @@ -89,11 +91,15 @@ jobs:
package = by_name.get(name)
if package is None:
raise SystemExit(f"failed to resolve workspace package metadata for {name}")
if package.get("publish") == []:
print(f"skip {name} (publish = false)", file=sys.stderr)
continue
print(f"{name}\t{package['version']}")
PY
)"

packages_to_publish=()
first_releases=()
while IFS=$'\t' read -r crate_name crate_version; do
[ -n "$crate_name" ] || continue
crate_state="$(
Expand Down Expand Up @@ -138,28 +144,41 @@ jobs:
echo "publish $crate_name $crate_version"
packages_to_publish+=("$crate_name")
else
echo "skip $crate_name $crate_version (crate not yet initialized on crates.io)"
if [[ "$mode" == "publish" && -z "$FIRST_PUBLISH_TOKEN" ]]; then
echo "::error::$crate_name needs its first publication. Configure the CARGO_REGISTRY_TOKEN repository secret for this CI release."
exit 1
fi
echo "publish $crate_name $crate_version (first release)"
packages_to_publish+=("$crate_name")
first_releases+=("$crate_name")
fi
done <<< "$package_versions"

if [[ "${#packages_to_publish[@]}" -eq 0 ]]; then
echo "no already-initialized crates need a new crates.io release"
echo "no workspace crates need a new crates.io release"
exit 0
fi

if [[ "$mode" == "dry-run" ]]; then
publish_args=(cargo publish --dry-run)
publish_args=(cargo publish --dry-run --locked)
echo "dry-run publish packages: ${packages_to_publish[*]}"
for package in "${packages_to_publish[@]}"; do
publish_args+=(-p "$package")
done
"${publish_args[@]}"
else
publish_args=(cargo publish)
echo "publish packages: ${packages_to_publish[*]}"
for package in "${packages_to_publish[@]}"; do
if [[ " ${first_releases[*]} " == *" $package "* ]]; then
echo "publish $package using first-release API token"
CARGO_REGISTRY_TOKEN="$FIRST_PUBLISH_TOKEN" cargo publish --locked -p "$package"
else
echo "publish $package using OIDC"
cargo publish --locked -p "$package"
fi
done
fi

for package in "${packages_to_publish[@]}"; do
publish_args+=(-p "$package")
done
"${publish_args[@]}"

- name: Create GitHub Release
if: github.ref_type == 'tag' && startsWith(github.ref_name, 'v')
env:
Expand All @@ -168,12 +187,27 @@ jobs:
set -euo pipefail
tag_ref="refs/tags/$GITHUB_REF_NAME"
git fetch --force origin "$tag_ref:$tag_ref"
tag_object="$(git rev-parse "$tag_ref^{tag}" 2>/dev/null || true)"
target_commit="$(git rev-parse "$tag_ref^{commit}")"
notes_file="$RUNNER_TEMP/release-notes.md"
git for-each-ref "$tag_ref" --format='%(contents)' > "$notes_file"
if [ ! -s "$notes_file" ]; then
git log -1 --format=%B "$target_commit" > "$notes_file"
fi
{
printf '\n## Authentication and provenance\n\n'
printf -- '- Tag: `%s`\n' "$GITHUB_REF_NAME"
if [ -n "$tag_object" ]; then
printf -- '- Annotated tag object: `%s`\n' "$tag_object"
else
printf -- '- Tag object: lightweight tag\n'
fi
printf -- '- Target commit: `%s`\n' "$target_commit"
printf -- '- Workflow run: %s/%s/actions/runs/%s\n' \
"$GITHUB_SERVER_URL" "$GITHUB_REPOSITORY" "$GITHUB_RUN_ID"
printf -- '- Workflow attempt: `%s`\n' "$GITHUB_RUN_ATTEMPT"
printf -- '- Published by: GitHub Actions `%s` workflow\n' "$GITHUB_WORKFLOW"
} >> "$notes_file"

if gh release view "$GITHUB_REF_NAME" --repo "$GITHUB_REPOSITORY" >/dev/null 2>&1; then
echo "github release $GITHUB_REF_NAME already exists"
Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,10 @@ refs/

doc
tmp/

# Local implementation notes and agent working documents
/docs/design/
/docs/api/sdk-interfaces.md
/docs/api/top-level-review.md
/docs/api/pishoo-service-boundary.md
/docs/reviews/
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# Changelog

## [0.7.0] - 2026-10-12

### Changed

- Migrate to independent named Endpoints, anonymous requests and shared QUIC networking.
- Use native HTTP/3 streams, standard bodies, streaming uploads and request trailers.
- Maintain interface bindings and NAT mappings, and evict unusable H3 connections.
- Restore Node.js and Python SDKs; retire the dhttp-identity workspace package.
- Update identity-home, access and log crates for the new API.

### Release versions

| Package | Previous published version | Prepared version |
| --- | --- | --- |
| `dhttp` | 0.6.2 | 0.7.0 |
| `dhttp-home` | 0.5.0 | 0.6.0 |
| `dhttp-access` | 0.4.2 | 0.5.0 |
| `dhttp-log` | 0.1.0 | 0.2.0 |
| `@genmeta/dhttp / dhttpy` | 0.6.2 | 0.7.0 |


## [0.6.2] - 2026-08-19

### Fixed
Expand Down
Loading
Loading