Skip to content

fix(tls): thread --tls-ca-file and --insecure-tls through the download engine - #550

Open
SuperCoolPencil wants to merge 6 commits into
mainfrom
fix-tls-cert
Open

fix(tls): thread --tls-ca-file and --insecure-tls through the download engine#550
SuperCoolPencil wants to merge 6 commits into
mainfrom
fix-tls-cert

Conversation

@SuperCoolPencil

@SuperCoolPencil SuperCoolPencil commented Jul 24, 2026

Copy link
Copy Markdown
Member

Problem

Fixes #549.

--tls-ca-file and --insecure-tls were wired into the remote-API HTTP client (service.NewHTTPTransport) but not into the NetworkPool used by the probe and download engines. The transport was created with a bare http.Transport and no TLSClientConfig, silently ignoring both flags for every actual download.

Alpine Linux's ca-certificates package does not include the Microsoft TLS RSA Root G2 root, so downloading from download.microsoft.com (Windows SDK, etc.) fails with:

tls: failed to verify certificate: x509: certificate signed by unknown authority

What changed

File Change
internal/utils/tls.go (new) BuildTLSConfig(caFile, insecure) — shared helper that appends to the system pool rather than replacing it
internal/service/http_client.go newTLSConfig delegates to utils.BuildTLSConfig — removes 30 lines of duplication
internal/types/config.go TLSCAFile / TLSInsecure added to RuntimeConfig; WithTLS() overlay helper
internal/transport/network.go Pool key includes TLS fields; AcquireTransport accepts 2 new params; createNewTransport sets TLSClientConfig
internal/probe/probe.go Forwards TLS fields from runCfg to AcquireTransport
internal/strategy/concurrent/downloader.go setupNetwork() forwards TLS from d.Runtime
internal/strategy/single/downloader.go Download() forwards TLS from d.Runtime
internal/orchestrator/manager.go DownloadRequest carries the flags; overlaid via WithTLS() at probe and download-record build
internal/scheduler/manager.go Mirror-probe inline config copies TLS fields
cmd/root_downloads.go Both DownloadRequest constructions inject CLI globals
docs/USAGE.md Global flags table + new TLS / Certificate Troubleshooting section

Key design choices

  • Append, not replace: BuildTLSConfig calls x509.SystemCertPool() and appends the user's PEM. Adding the Microsoft root doesn't break verification for any other host.
  • Pool-keyed by TLS config: Downloads with different CA files or insecure flags get separate transport instances — correct isolation, no cross-contamination.
  • Single source of truth: utils.BuildTLSConfig is shared by both transport code paths; the old inline copy in service/http_client.go is gone.
  • Minimal diff: The CLI flag variables (globalTLSCAFile, globalInsecureTLS) already existed and are merely threaded through rather than re-declared.

Testing

All existing tests pass. Added TestNetworkPool_TLSKeyIsolation in transport/network_test.go to verify:

  • Different TLS configs produce distinct pool entries
  • insecure=true correctly sets InsecureSkipVerify on the transport
  • Pool reuse still works for identical configs
ok  github.com/SurgeDM/Surge/internal/transport    0.37s
ok  github.com/SurgeDM/Surge/internal/utils        0.11s
ok  github.com/SurgeDM/Surge/internal/service      0.73s
ok  github.com/SurgeDM/Surge/internal/probe        2.21s
ok  github.com/SurgeDM/Surge/internal/strategy/concurrent  14.7s
ok  github.com/SurgeDM/Surge/internal/strategy/single      1.55s
ok  github.com/SurgeDM/Surge/internal/types        0.01s

Greptile Summary

This PR propagates CLI TLS options through probing and download transports.

  • Adds a shared helper that builds TLS configurations from the system roots, an optional CA bundle, and insecure mode.
  • Includes TLS settings in transport-pool identity and forwards transport-construction errors.
  • Carries TLS values through runtime configuration, orchestration, scheduling, and both download strategies.
  • Adds TLS usage documentation and transport isolation tests.

Confidence Score: 4/5

This PR is not safe to merge until per-download TLS state is persisted so cold resumes retain the original trust configuration.

The new resume logic reads TLS values exclusively from Runtime fields that persistence explicitly omits, leaving restarted custom-CA and insecure downloads unable to recover their required TLS settings.

internal/orchestrator/pause_resume.go, internal/types/models.go

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex attempted a cold resume verification by running the cross-process persistence harness, but the test could not complete because the step budget was exhausted.
  • The initial same-process test persisted and reloaded both records but retained TLS runtime fields, so it did not simulate a genuine cold restart.
  • A cross-process test invocation initially failed to compile due to a package-level URL constant conflict; after correcting the harness, it could not be rerun within the step budget.
  • Focused PR tests reported TLS-runtime validation metrics and timing, with the runtime harness returning data under TLS and the baseline harness failing to compile due to missing TLS fields in RuntimeConfig.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
internal/transport/network.go Extends transport pooling with TLS-aware keys, TLS configuration construction, and explicit error propagation.
internal/utils/tls.go Adds the shared TLS configuration helper used by API and download transports.
internal/orchestrator/manager.go Overlays request TLS options onto probe and download runtime configuration.
internal/orchestrator/pause_resume.go Attempts to restore TLS options during resume, but cold-resume inputs cannot contain the excluded Runtime field.
internal/probe/probe.go Forwards runtime TLS options into probe transport acquisition.
internal/strategy/concurrent/downloader.go Applies runtime TLS configuration to concurrent download transports and propagates setup errors.
internal/strategy/single/downloader.go Applies runtime TLS configuration to single-download transports and propagates acquisition errors.
internal/types/config.go Adds runtime TLS fields and an overlay helper used by orchestration.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  CLI[CLI TLS flags] --> Req[DownloadRequest]
  Req --> Runtime[RuntimeConfig]
  Runtime --> Probe[Probe transport]
  Runtime --> Download[Download transport]
  Runtime -. excluded from persistence .-> Store[(Persistent state)]
  Store --> Resume[Cold resume]
  Resume --> Defaults[Current settings]
  Defaults --> Download
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
internal/orchestrator/pause_resume.go:373-386
**Cold resume drops TLS state**

When a download requiring a custom CA or insecure mode is paused and resumed after a restart, both records loaded from storage have a nil `Runtime` because that field is excluded from gob serialization. These branches are therefore skipped and the resumed download uses current settings instead of its original TLS configuration, causing certificate verification to fail or verification to be re-enabled.

Reviews (3): Last reviewed commit: "fix(tls): address code review issues wit..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

Summary by CodeRabbit

  • New Features

    • Added global options for custom TLS CA certificates and insecure TLS connections.
    • Download requests now support and preserve TLS settings across queued, resumed, and active downloads.
    • Added TLS troubleshooting guidance for certificate issues, Docker, and Alpine environments.
  • Bug Fixes

    • Invalid or unreadable TLS certificates now produce clear download errors.
    • Improved transport reuse while keeping distinct TLS configurations isolated.

Comment thread internal/transport/network.go
Comment thread internal/orchestrator/manager.go
Comment thread internal/orchestrator/manager.go
Comment thread internal/orchestrator/manager.go
@SuperCoolPencil

SuperCoolPencil commented Aug 2, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The change adds global and per-download TLS CA file and insecure-TLS settings. The settings flow through runtime configuration, transport pooling, probing, downloading, persistence, and resume handling. CLI documentation now describes TLS flags and certificate troubleshooting.

Changes

TLS configuration flow

Layer / File(s) Summary
TLS configuration contracts
internal/types/config.go, internal/utils/tls.go, internal/config/settings.go, internal/service/http_client.go, cmd/root.go, cmd/root_downloads.go
Runtime configuration and TLS construction support custom CA files and insecure TLS. CLI values populate runtime and download requests.
TLS-aware transport pooling
internal/transport/network.go, internal/transport/network_test.go, internal/strategy/concurrent/prewarm_reuse_test.go, internal/strategy/single/downloader_test.go
Transport pooling includes normalized TLS settings in pool keys. TLS errors now return from transport acquisition. Tests cover isolation, reuse, invalid CA files, and path normalization.
Download and probe propagation
internal/orchestrator/manager.go, internal/probe/probe.go, internal/scheduler/manager.go, internal/strategy/concurrent/downloader.go, internal/strategy/single/downloader.go, internal/types/models.go
Probe and download paths pass TLS settings to transport acquisition. Setup errors stop downloads. Download records retain TLS settings.
Resume behavior and usage support
internal/orchestrator/pause_resume.go, internal/strategy/concurrent/downloader_helpers_test.go, docs/USAGE.md
Resume logic restores TLS settings from saved state or download entries. Snapshot tests verify persistence. Documentation describes TLS flags, CA files, insecure TLS, and Docker/Alpine certificate setup.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant DownloadRequest
  participant Scheduler
  participant ProbeServerWithProxy
  participant NetworkPool
  participant Downloader
  CLI->>DownloadRequest: provide TLSCAFile and TLSInsecure
  DownloadRequest->>Scheduler: retain TLS settings
  Scheduler->>ProbeServerWithProxy: pass runtime TLS settings
  ProbeServerWithProxy->>NetworkPool: acquire TLS-aware transport
  NetworkPool-->>ProbeServerWithProxy: return transport or error
  Scheduler->>Downloader: start download with TLS settings
  Downloader->>NetworkPool: acquire matching transport
Loading

Suggested reviewers: supergekfordj

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes threading the TLS CA file and insecure TLS options through the download engine.
Linked Issues check ✅ Passed The changes support custom CA certificates and insecure TLS, propagate settings through downloads, and preserve them across cold resumes for issue #549.
Out of Scope Changes check ✅ Passed The code, tests, and documentation changes are directly related to TLS configuration and the linked certificate verification issue.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@SurgeDM SurgeDM deleted a comment from greptile-apps Bot Aug 2, 2026
@SurgeDM SurgeDM deleted a comment from greptile-apps Bot Aug 2, 2026
@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 5

🤖 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.

Inline comments:
In `@docs/USAGE.md`:
- Around line 77-93: Update the “Missing root certificate” workaround in the
documentation to download and convert the Microsoft TLS RSA Root G2 certificate,
matching the certificate named in the explanation; keep the existing Surge
--tls-ca-file usage and command flow unchanged.

In `@internal/orchestrator/manager.go`:
- Line 218: Update enqueueResolved around the ProbeServerWithProxy call to
detect the typed transport-configuration error caused by invalid or unreadable
TLSCAFile and return it directly instead of classifying it as a non-terminal
probe failure. Ensure the existing enqueue behavior remains unchanged for other
probe errors, and expose or reuse the typed transport error from the probing
transport setup.
- Line 350: Update the synchronous persisted download record creation near the
existing state persistence to include req.TLSCAFile and req.TLSInsecure, then
restore those values into the resumed request or settings before RunDownload.
Keep the runtime config construction in WithTLS aligned with the restored
persisted values so cold resumes retain the original TLS configuration.

In `@internal/strategy/single/downloader_test.go`:
- Around line 317-320: Update TestNewSingleDownloader_TransportReuse to check
the error returned by each AcquireTransport call before using the transport;
fail the test immediately when acquisition fails, then defer ReleaseTransport
and compare the successfully acquired transports.

In `@internal/transport/network.go`:
- Around line 59-63: Normalize tlsCAFile using the same trimming behavior as
BuildTLSConfig before constructing poolKey or creating a transport, so
equivalent CA paths reuse one pool. Update the transport acquisition flow around
createNewTransport and add a regression test that acquires transports with
trimmed and whitespace-padded CA paths and verifies they share the transport
pool.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 459f5f25-9bca-4511-bb10-c75477129379

📥 Commits

Reviewing files that changed from the base of the PR and between 633b1fd and f7ad27f.

📒 Files selected for processing (20)
  • cmd/root.go
  • cmd/root_downloads.go
  • docs/USAGE.md
  • internal/config/settings.go
  • internal/orchestrator/manager.go
  • internal/orchestrator/pause_resume.go
  • internal/probe/probe.go
  • internal/scheduler/manager.go
  • internal/service/http_client.go
  • internal/service/local_service_test.go
  • internal/strategy/concurrent/concurrent_test.go
  • internal/strategy/concurrent/downloader.go
  • internal/strategy/concurrent/prewarm_reuse_test.go
  • internal/strategy/single/downloader.go
  • internal/strategy/single/downloader_test.go
  • internal/transport/network.go
  • internal/transport/network_test.go
  • internal/types/config.go
  • internal/utils/http_test.go
  • internal/utils/tls.go

Comment thread docs/USAGE.md
Comment thread internal/orchestrator/manager.go
Comment thread internal/orchestrator/manager.go
Comment thread internal/strategy/single/downloader_test.go Outdated
Comment thread internal/transport/network.go
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown

Binary Size Analysis

⚠️ Size Increased

Version Human Readable Raw Bytes
Main 17.45 MB 18301220
PR 17.46 MB 18309412
Difference 8.00 KB 8192

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal/transport/network.go (1)

52-55: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Partition ClientSessionCache entries by effective TLS policy.

NetworkPool keys transports by tlsCAFile and tlsInsecure, but every TLS config is wired to sharedClientSessionCache. For Go modules using this package, a cached session established with a private CA can be offered to a later pool transport with a different, including system-default, trust policy. Partition the cache, or disable resumption for transported clients unless resumption policy is also a required test assertion. Add a regression test that establishes a session with one CA policy and attempts resumption with another policy.

🤖 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 `@internal/transport/network.go` around lines 52 - 55, Update
sharedClientSessionCache usage in NetworkPool TLS configuration to partition
ClientSessionCache entries by effective TLS policy, including tlsCAFile and
tlsInsecure, so sessions cannot cross trust-policy boundaries. Preserve session
resumption within the same policy, and add a regression test that establishes a
session under one CA policy then verifies it is not resumed under a different
policy.
🤖 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.

Inline comments:
In `@internal/transport/network_test.go`:
- Around line 18-19: Update all affected tests in network_test.go to capture and
assert errors from every AcquireTransport call with t.Fatalf before
dereferencing or releasing the returned transport. Ensure the cache, HTTP/2, and
reuse tests always use the successfully acquired pool transport, and in the
idle-timer test assign the reacquired transport to a variable and release it to
keep leases balanced.

In `@internal/types/models.go`:
- Around line 72-73: Update ConcurrentDownloader.saveStateSnapshot to copy
TLSCAFile and TLSInsecure from d.Runtime into every DownloadRecord literal used
for pause-event and direct state saves, preserving the configured TLS values
across cold resumes. Add a cold-resume test verifying both the CA path and
insecure mode survive snapshot restoration.

---

Outside diff comments:
In `@internal/transport/network.go`:
- Around line 52-55: Update sharedClientSessionCache usage in NetworkPool TLS
configuration to partition ClientSessionCache entries by effective TLS policy,
including tlsCAFile and tlsInsecure, so sessions cannot cross trust-policy
boundaries. Preserve session resumption within the same policy, and add a
regression test that establishes a session under one CA policy then verifies it
is not resumed under a different policy.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fb403897-2bf3-4512-aad1-291a2ab8b6c6

📥 Commits

Reviewing files that changed from the base of the PR and between f7ad27f and 5e33bb7.

📒 Files selected for processing (9)
  • cmd/root_downloads.go
  • docs/USAGE.md
  • internal/orchestrator/manager.go
  • internal/orchestrator/pause_resume.go
  • internal/strategy/concurrent/downloader.go
  • internal/strategy/single/downloader_test.go
  • internal/transport/network.go
  • internal/transport/network_test.go
  • internal/types/models.go
🚧 Files skipped from review as they are similar to previous changes (6)
  • internal/orchestrator/pause_resume.go
  • docs/USAGE.md
  • internal/strategy/single/downloader_test.go
  • cmd/root_downloads.go
  • internal/strategy/concurrent/downloader.go
  • internal/orchestrator/manager.go

Comment thread internal/transport/network_test.go Outdated
Comment thread internal/types/models.go
Comment on lines +72 to +73
TLSCAFile string `json:"tls_ca_file,omitempty"`
TLSInsecure bool `json:"tls_insecure,omitempty"`

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Persist TLS settings in every resume snapshot.

TLSCAFile and TLSInsecure are marked persistent here, but ConcurrentDownloader.saveStateSnapshot omits them from its DownloadRecord literal. Both the pause event state and direct state save can therefore contain zero TLS values. A state-only cold resume can lose the original CA path or insecure mode.

Copy the values from d.Runtime before saving and add a cold-resume test.

Suggested snapshot fields
 	Workers:      d.Runtime.Workers,
 	MinChunkSize: d.Runtime.MinChunkSize,
+	TLSCAFile:    d.Runtime.TLSCAFile,
+	TLSInsecure:  d.Runtime.TLSInsecure,
🤖 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 `@internal/types/models.go` around lines 72 - 73, Update
ConcurrentDownloader.saveStateSnapshot to copy TLSCAFile and TLSInsecure from
d.Runtime into every DownloadRecord literal used for pause-event and direct
state saves, preserving the configured TLS values across cold resumes. Add a
cold-resume test verifying both the CA path and insecure mode survive snapshot
restoration.

@SuperCoolPencil
SuperCoolPencil force-pushed the fix-tls-cert branch 2 times, most recently from f5da554 to 1076475 Compare August 2, 2026 08:55

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
internal/transport/network_test.go (1)

344-375: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Test session-cache isolation for different CA files.

This test only separates the default and insecure TLS policies. A regression that keys the session cache by tlsInsecure but not tlsCAFile would pass. Add two valid, distinct CA files and assert that their transports use different session caches.

🤖 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 `@internal/transport/network_test.go` around lines 344 - 375, Extend
TestNetworkPool_SessionCachePartitioning to create two valid, distinct CA files
and acquire transports using each CA path with the same TLS security settings.
Assert their TLSClientConfig.ClientSessionCache values differ, while preserving
the existing checks for insecure/default policy isolation and same-policy cache
reuse.
🤖 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 `@internal/transport/network_test.go`:
- Around line 344-375: Extend TestNetworkPool_SessionCachePartitioning to create
two valid, distinct CA files and acquire transports using each CA path with the
same TLS security settings. Assert their TLSClientConfig.ClientSessionCache
values differ, while preserving the existing checks for insecure/default policy
isolation and same-policy cache reuse.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bc58b315-4692-4c64-bbe2-c474442babe5

📥 Commits

Reviewing files that changed from the base of the PR and between f5da554 and 1076475.

📒 Files selected for processing (9)
  • docs/USAGE.md
  • internal/orchestrator/manager.go
  • internal/orchestrator/pause_resume.go
  • internal/strategy/concurrent/downloader.go
  • internal/strategy/concurrent/downloader_helpers_test.go
  • internal/strategy/single/downloader_test.go
  • internal/transport/network.go
  • internal/transport/network_test.go
  • internal/types/models.go
🚧 Files skipped from review as they are similar to previous changes (7)
  • internal/strategy/concurrent/downloader_helpers_test.go
  • internal/types/models.go
  • internal/orchestrator/manager.go
  • internal/orchestrator/pause_resume.go
  • internal/strategy/single/downloader_test.go
  • docs/USAGE.md
  • internal/strategy/concurrent/downloader.go

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown

❌ Test Failures on ubuntu-latest

  • github.com/SurgeDM/Surge/internal/service: TestLocalDownloadService_AddWithID_UsesProvidedID

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.

TLS certificate verification fails when downloading Windows SDK in the latest Surge Docker image

1 participant