Skip to content

Commit 7d5b6c7

Browse files
fix: pass configured http headers to network extension (#52)
I forgot to do this..
1 parent fc0f5b0 commit 7d5b6c7

File tree

8 files changed

+32
-16
lines changed

8 files changed

+32
-16
lines changed

Coder Desktop/Coder Desktop/State.swift

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@ class AppState: ObservableObject {
3131

3232
@Published var useLiteralHeaders: Bool = UserDefaults.standard.bool(forKey: Keys.useLiteralHeaders) {
3333
didSet {
34+
if let onChange { onChange(tunnelProviderProtocol()) }
3435
guard persistent else { return }
3536
UserDefaults.standard.set(useLiteralHeaders, forKey: Keys.useLiteralHeaders)
3637
}
3738
}
3839

3940
@Published var literalHeaders: [LiteralHeader] {
4041
didSet {
42+
if let onChange { onChange(tunnelProviderProtocol()) }
4143
guard persistent else { return }
4244
try? UserDefaults.standard.set(JSONEncoder().encode(literalHeaders), forKey: Keys.literalHeaders)
4345
}
@@ -57,13 +59,17 @@ class AppState: ObservableObject {
5759
// HACK: We can't write to the system keychain, and the user keychain
5860
// isn't accessible, so we'll use providerConfiguration, which is over XPC.
5961
proto.providerConfiguration = ["token": sessionToken!]
62+
if useLiteralHeaders, let headers = try? JSONEncoder().encode(literalHeaders) {
63+
proto.providerConfiguration?["literalHeaders"] = headers
64+
}
6065
proto.serverAddress = baseAccessURL!.absoluteString
6166
return proto
6267
}
6368

6469
private let keychain: Keychain
6570
private let persistent: Bool
6671

72+
// This closure must be called when any property used to configure the VPN changes
6773
let onChange: ((NETunnelProviderProtocol?) -> Void)?
6874

6975
public init(onChange: ((NETunnelProviderProtocol?) -> Void)? = nil,
@@ -125,20 +131,20 @@ class AppState: ObservableObject {
125131
}
126132

127133
struct LiteralHeader: Hashable, Identifiable, Equatable, Codable {
128-
var header: String
134+
var name: String
129135
var value: String
130136
var id: String {
131-
"\(header):\(value)"
137+
"\(name):\(value)"
132138
}
133139

134-
init(header: String, value: String) {
135-
self.header = header
140+
init(name: String, value: String) {
141+
self.name = name
136142
self.value = value
137143
}
138144
}
139145

140146
extension LiteralHeader {
141147
func toSDKHeader() -> HTTPHeader {
142-
.init(header: header, value: value)
148+
.init(name: name, value: value)
143149
}
144150
}

Coder Desktop/Coder Desktop/Views/Settings/LiteralHeaderModal.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ struct LiteralHeaderModal: View {
2626
}.padding(20)
2727
}.onAppear {
2828
if let existingHeader {
29-
header = existingHeader.header
29+
header = existingHeader.name
3030
value = existingHeader.value
3131
}
3232
}
@@ -37,7 +37,7 @@ struct LiteralHeaderModal: View {
3737
if let existingHeader {
3838
state.literalHeaders.removeAll { $0 == existingHeader }
3939
}
40-
let newHeader = LiteralHeader(header: header, value: value)
40+
let newHeader = LiteralHeader(name: header, value: value)
4141
if !state.literalHeaders.contains(newHeader) {
4242
state.literalHeaders.append(newHeader)
4343
}

Coder Desktop/Coder Desktop/Views/Settings/LiteralHeadersSection.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ struct LiteralHeadersSection<VPN: VPNService>: View {
2020
.controlSize(.large)
2121

2222
Table(state.literalHeaders, selection: $selectedHeader) {
23-
TableColumn("Header", value: \.header)
23+
TableColumn("Header", value: \.name)
2424
TableColumn("Value", value: \.value)
2525
}.opacity(state.useLiteralHeaders ? 1 : 0.5)
2626
.frame(minWidth: 400, minHeight: 200)

Coder Desktop/CoderSDK/Client.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public struct Client {
3333
if let token { req.addValue(token, forHTTPHeaderField: Headers.sessionToken) }
3434
req.httpMethod = method.rawValue
3535
for header in headers {
36-
req.addValue(header.value, forHTTPHeaderField: header.header)
36+
req.addValue(header.value, forHTTPHeaderField: header.name)
3737
}
3838
req.httpBody = body
3939
let data: Data

Coder Desktop/CoderSDK/HTTP.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ public struct HTTPResponse {
66
let req: URLRequest
77
}
88

9-
public struct HTTPHeader: Sendable {
10-
public let header: String
9+
public struct HTTPHeader: Sendable, Codable {
10+
public let name: String
1111
public let value: String
12-
public init(header: String, value: String) {
13-
self.header = header
12+
public init(name: String, value: String) {
13+
self.name = name
1414
self.value = value
1515
}
1616
}

Coder Desktop/CoderSDKTests/CoderSDKTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ struct CoderSDKTests {
2828

2929
let url = URL(string: "https://example.com")!
3030
let token = "fake-token"
31-
let client = Client(url: url, token: token, headers: [.init(header: "X-Test-Header", value: "foo")])
31+
let client = Client(url: url, token: token, headers: [.init(name: "X-Test-Header", value: "foo")])
3232
var mock = try Mock(
3333
url: url.appending(path: "api/v2/users/johndoe"),
3434
contentType: .json,

Coder Desktop/VPN/Manager.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ actor Manager {
5454
do {
5555
try tunnelHandle = TunnelHandle(dylibPath: dest)
5656
} catch {
57-
logger.error("couldn't open dylib \(error, privacy: .public)")
5857
throw .tunnelSetup(error)
5958
}
6059
speaker = await Speaker<Vpn_ManagerMessage, Vpn_TunnelMessage>(
@@ -164,6 +163,12 @@ actor Manager {
164163
req.tunnelFileDescriptor = tunFd
165164
req.apiToken = cfg.apiToken
166165
req.coderURL = cfg.serverUrl.absoluteString
166+
req.headers = cfg.literalHeaders.map { header in
167+
.with { req in
168+
req.name = header.name
169+
req.value = header.value
170+
}
171+
}
167172
}
168173
})
169174
} catch {
@@ -223,6 +228,7 @@ actor Manager {
223228
struct ManagerConfig {
224229
let apiToken: String
225230
let serverUrl: URL
231+
let literalHeaders: [HTTPHeader]
226232
}
227233

228234
enum ManagerError: Error {

Coder Desktop/VPN/PacketTunnelProvider.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import CoderSDK
12
import NetworkExtension
23
import os
34
import VPNLib
@@ -65,6 +66,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
6566
completionHandler(makeNSError(suffix: "PTP", desc: "Missing Token"))
6667
return
6768
}
69+
let headers: [HTTPHeader] = (proto.providerConfiguration?["literalHeaders"] as? Data)
70+
.flatMap { try? JSONDecoder().decode([HTTPHeader].self, from: $0) } ?? []
6871
logger.debug("retrieved token & access URL")
6972
let completionHandler = CallbackWrapper(completionHandler)
7073
Task {
@@ -73,7 +76,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable {
7376
let manager = try await Manager(
7477
with: self,
7578
cfg: .init(
76-
apiToken: token, serverUrl: .init(string: baseAccessURL)!
79+
apiToken: token, serverUrl: .init(string: baseAccessURL)!,
80+
literalHeaders: headers
7781
)
7882
)
7983
globalXPCListenerDelegate.vpnXPCInterface.manager = manager

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy