From a075a2f2531248f5820799e927561f4d8e463bea Mon Sep 17 00:00:00 2001 From: Ethan Dickson Date: Mon, 22 Jun 2026 04:29:00 +0000 Subject: [PATCH 1/2] fix: plumb literal headers through Helper HTTP requests The Helper process makes two HTTP requests to the Coder server during Manager.init that were not attaching configured literal headers: 1. Client(url:) for buildInfo() had no headers, so reverse proxies like Cloudflare Access would block the request. 2. download() for the coder binary used a plain URLSession with no headers. Both call sites now pass cfg.literalHeaders. The download() function in VPNLib/Download.swift is extended to accept and apply headers to the URLRequest. --- Coder-Desktop/Coder-DesktopHelper/Manager.swift | 5 +++-- Coder-Desktop/VPNLib/Download.swift | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Coder-Desktop/Coder-DesktopHelper/Manager.swift b/Coder-Desktop/Coder-DesktopHelper/Manager.swift index 778088d6..df79d8a1 100644 --- a/Coder-Desktop/Coder-DesktopHelper/Manager.swift +++ b/Coder-Desktop/Coder-DesktopHelper/Manager.swift @@ -41,7 +41,7 @@ actor Manager { "Failed to create directories for binary destination (\(dest)): \(error.localizedDescription)" ) } - let client = Client(url: cfg.serverUrl) + let client = Client(url: cfg.serverUrl, headers: cfg.literalHeaders) let buildInfo: BuildInfoResponse do { buildInfo = try await client.buildInfo() @@ -67,7 +67,8 @@ actor Manager { try await download( src: binaryPath, dest: dest, - urlSession: URLSession(configuration: sessionConfig) + urlSession: URLSession(configuration: sessionConfig), + headers: cfg.literalHeaders ) { progress in pushProgress(stage: .downloading, downloadProgress: progress) } diff --git a/Coder-Desktop/VPNLib/Download.swift b/Coder-Desktop/VPNLib/Download.swift index 37c53ec5..25685620 100644 --- a/Coder-Desktop/VPNLib/Download.swift +++ b/Coder-Desktop/VPNLib/Download.swift @@ -1,3 +1,4 @@ +import CoderSDK import CryptoKit import Foundation @@ -5,12 +6,14 @@ public func download( src: URL, dest: URL, urlSession: URLSession, + headers: [HTTPHeader] = [], progressUpdates: (@Sendable (DownloadProgress) -> Void)? = nil ) async throws(DownloadError) { try await DownloadManager().download( src: src, dest: dest, urlSession: urlSession, + headers: headers, progressUpdates: progressUpdates.flatMap { throttle(interval: .milliseconds(10), $0) } ) } @@ -54,9 +57,13 @@ private final class DownloadManager: NSObject, @unchecked Sendable { src: URL, dest: URL, urlSession: URLSession, + headers: [HTTPHeader] = [], progressUpdates: (@Sendable (DownloadProgress) -> Void)? ) async throws(DownloadError) { var req = URLRequest(url: src) + for header in headers { + req.setValue(header.value, forHTTPHeaderField: header.name) + } if FileManager.default.fileExists(atPath: dest.path) { if let existingFileData = try? Data(contentsOf: dest, options: .mappedIfSafe) { req.setValue(etag(data: existingFileData), forHTTPHeaderField: "If-None-Match") From 62aa78f8a704ca37e495a5ac78fac91c2cb99b25 Mon Sep 17 00:00:00 2001 From: Ethan Dickson Date: Mon, 22 Jun 2026 04:43:55 +0000 Subject: [PATCH 2/2] fix: preserve duplicate literal header values in binary download --- Coder-Desktop/VPNLib/Download.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Coder-Desktop/VPNLib/Download.swift b/Coder-Desktop/VPNLib/Download.swift index 25685620..3441b982 100644 --- a/Coder-Desktop/VPNLib/Download.swift +++ b/Coder-Desktop/VPNLib/Download.swift @@ -62,7 +62,7 @@ private final class DownloadManager: NSObject, @unchecked Sendable { ) async throws(DownloadError) { var req = URLRequest(url: src) for header in headers { - req.setValue(header.value, forHTTPHeaderField: header.name) + req.addValue(header.value, forHTTPHeaderField: header.name) } if FileManager.default.fileExists(atPath: dest.path) { if let existingFileData = try? Data(contentsOf: dest, options: .mappedIfSafe) {