Skip to content

feat: Windows x64 and ARM64 support for decdn-sponsored - #7

Merged
alpergundogdu merged 7 commits into
mainfrom
feat/windows
Sep 24, 2026
Merged

alpergundogdu merged 7 commits into
mainfrom
feat/windows

Conversation

@alpergundogdu

Copy link
Copy Markdown
Contributor

Summary

Windows at launch, on x64 and ARM64. Stacked on #6 (base: feat/decdn-sponsored).

  • Installer: GET /decdn.ps1 serves a PowerShell twin of decdn.sh, filled in from the same config. On Windows the website shows:
    irm https://up.decdn.org/decdn.ps1 | iex; decdn-sponsored pull b3:<hash>
    • Installs decdn.exe and decdn-sponsored.exe to %LOCALAPPDATA%\decdn\bin and adds that to PATH, both for the user and for the running session, so the next command on the same line finds them.
    • Writes the same sponsor.toml profile, with forward-slash paths (no TOML escaping) and no byte-order mark (which Windows PowerShell 5.1 would otherwise add).
    • Detects the OS architecture, so x64 PowerShell running under emulation on ARM64 still installs ARM64 binaries.
    • Runs inside one script block, so irm | iex leaves no variables or preferences behind in the user's session, and it never calls exit (which would close their window).
  • decdn.sh: now normalizes architectures to x86_64/aarch64, so /dl/<bin>-<os>-<arch> names match on every platform.
  • Wrapper:
    • Finds the home directory with std::env::home_dir, because HOME is unset on Windows.
    • Opens the captcha link through rundll32 url.dll,FileProtocolHandler, which skips cmd's special-character parsing.
  • Tests: the pull-flow tests run on Windows with a .cmd stub for decdn. A contract test covers GET /decdn.ps1.
  • CI (the repo's first workflow):
    • Linux: fmt, clippy and tests across the whole workspace.
    • macOS and Windows x64: clippy and tests for the client crate.
    • Windows ARM64: clippy for the client crate.
    • decdn/decdn is checked out alongside sponsord so the ../decdn path dependencies resolve.

Merge order: the Windows CI legs build against decdn main, which compiles for Windows only after decdn/decdn#2146 lands.

Test plan

  • macOS: cargo fmt --check, cargo clippy --workspace --all-targets -D warnings, cargo test --workspace (31 passed)
  • decdn.ps1 under real PowerShell (mcr.microsoft.com/powershell, ARM64) against a fake gateway: 0 parse errors; irm | iex installs both binaries; the profile is correct; PATH is updated for the session; nothing leaks into the caller's scope; ARM64 detected; the one-call form passes pull b3:… through to decdn-sponsored.exe
  • decdn.exe (from feat(cli): build the user CLI for Windows x64 and ARM64 decdn#2146) built with cross and run under Wine: key-gen then whoami agree on the address
  • Windows CI on MSVC runners, once feat(cli): build the user CLI for Windows x64 and ARM64 decdn#2146 merges. A local mingw debug build of the client tests can't link, because GNU ld exports every symbol of iroh-relay's cdylib and overflows the 65,535 export limit. MSVC isn't affected.

🤖 Generated with Claude Code

alpergundogdu and others added 3 commits September 24, 2026 14:53
Rename the onramp CLI to decdn-sponsored and replace `onramp <hash>` with
`decdn-sponsored pull <hash> [-o <dir>]`, which delegates to
`decdn bundle pull`.

- Each download gets its own throwaway key and random password under
  ~/.decdn/sponsored/downloads/<hash>/; the user never manages a
  keystore or password. The installer no longer generates a key.
- The capability is saved beside the key and reused on re-run, so an
  interrupted pull resumes without a new captcha. A capability near
  expiry is replaced by a fresh key. State is deleted on success.
- Hash-only input (b3:<hex> or hex); name resolution stays on the website.
- decdn runs with inherited stdio; stderr classification is removed.
- The installer passes its arguments through, so
  `curl .../decdn.sh | sh -s -- pull b3:<hash>` installs and downloads.
- Capability defaults: $5 cap, 48h TTL.
- Server moves from the removed decdn-client-pull crate to decdn-client
  so the workspace builds again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…assword

- Create the per-download state dirs with mode 0700 via DirBuilder, so
  the directory holding key material is never briefly world-readable.
- A keystore whose password file is missing cannot sign: replace it,
  together with the capability bound to it, instead of letting
  `decdn bundle pull` fail with a low-signal error. The flow now checks
  for a capability after ensure_key so the replacement is picked up.
- Correct Session::capability's doc: only malformed contents read as
  None; an unreadable file is an error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- installer: GET /decdn.ps1 serves a PowerShell twin of decdn.sh,
  templated from the same config. It installs decdn.exe and
  decdn-sponsored.exe to %LOCALAPPDATA%\decdn\bin, puts that on PATH
  (for the user and the running session), and writes the same profile
  with forward-slash paths and no BOM. It picks the OS architecture, so
  x64 PowerShell under emulation on ARM64 still installs ARM64 binaries,
  and runs in one script block so `irm | iex` leaves nothing behind.
- decdn.sh names architectures x86_64/aarch64 like the Windows script,
  so /dl/<bin>-<os>-<arch> is uniform.
- wrapper: resolve the home directory with std::env::home_dir (HOME is
  unset on Windows) and open the captcha link through
  `rundll32 url.dll,FileProtocolHandler` there.
- tests: the pull-flow tests run on Windows with a .cmd stub for decdn;
  a contract test covers GET /decdn.ps1.
- ci: first workflow. Linux runs the workspace (fmt, clippy, tests);
  macOS and Windows x64 lint and test the client; Windows ARM64 lints it.
  decdn/decdn is checked out beside sponsord for the path dependencies.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 24, 2026 15:08

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The wrapper’s Windows test stub likely isn’t spawnable as written and the new home-directory implementation uses a deprecated API that can break -D warnings builds.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 2 High severity · 1 Medium severity

Open (3)
What changed in this PR

Adds first-class Windows support (x64 + ARM64) for the decdn-sponsored installer and wrapper flow, including a PowerShell installer endpoint, Windows-aware wrapper behavior, expanded tests, and initial cross-platform CI coverage.

Changes:

  • Add GET /decdn.ps1 and a templated PowerShell installer (assets/decdn.ps1) alongside the existing POSIX installer.
  • Update wrapper behavior for Windows (home directory resolution; browser-opening strategy) and extend pull-flow tests to run on Windows.
  • Introduce a CI workflow covering Linux workspace checks plus macOS/Windows client lint+tests (including Windows ARM64 lint).
File Description
README.md Documents Windows installer usage and new /decdn.ps1 endpoint.
crates/​wrapper/​tests/​pull_flow.rs Adds Windows .cmd-based decdn stub for pull-flow tests.
crates/​wrapper/​src/​flow.rs Uses rundll32 url.dll,FileProtocolHandler to open URLs on Windows.
crates/​wrapper/​src/​config.rs Switches home directory discovery to support Windows.
crates/​server/​tests/​http_contract.rs Adds contract coverage for templated /decdn.ps1.
crates/​server/​src/​http/​mod.rs Routes /decdn.sh and /decdn.ps1 to distinct handlers.
crates/​server/​src/​http/​installer.rs Refactors installer rendering and adds PowerShell script handler.
crates/​server/​assets/​decdn.sh Normalizes arch values to x86_64/aarch64 for binary naming.
crates/​server/​assets/​decdn.ps1 Adds a Windows installer script that installs binaries and writes sponsor.toml.
.github/​workflows/​ci.yml Adds initial multi-OS CI, including Windows ARM64 clippy for the client crate.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread crates/wrapper/src/config.rs
Comment thread crates/wrapper/tests/pull_flow.rs
Comment thread crates/server/assets/decdn.ps1 Outdated
alpergundogdu and others added 2 commits September 24, 2026 16:16
- ci: `rustup target add` from inside the checkout, so the Windows ARM64
  target lands on the toolchain rust-toolchain.toml pins (the action's
  `targets:` went to its own toolchain, leaving no aarch64 std).
- decdn.ps1: the TLS protocol list is process-wide, so save it and
  restore it in a `finally` instead of leaving it changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alpergundogdu
alpergundogdu changed the base branch from feat/decdn-sponsored to main September 24, 2026 15:26
alpergundogdu and others added 2 commits September 24, 2026 16:26
# Conflicts:
#	README.md
#	crates/server/assets/decdn.sh
#	crates/wrapper/src/config.rs
#	crates/wrapper/src/flow.rs
#	crates/wrapper/tests/pull_flow.rs
The test faked the home directory by setting HOME, which Windows does
not consult (home_dir reads the profile folder there), so it failed on
the Windows runner while the code was right. Compare against home()
instead, and drop the now-unused serial_test dev-dependency.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@alpergundogdu
alpergundogdu merged commit 7d324b1 into main Sep 24, 2026
4 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