Skip to content

Commit 1700804

Browse files
authored
feat: add cloudflared protocol selection for tunnels in settings and UI (#91)
1 parent 3e0f7fc commit 1700804

File tree

13 files changed

+169
-6
lines changed

13 files changed

+169
-6
lines changed

platforms/macos/Sources/AppState.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ extension Defaults.Keys {
1212
static let useTreeView = Key<Bool>("useTreeView", default: false)
1313
static let hideSystemProcesses = Key<Bool>("hideSystemProcesses", default: false)
1414
static let refreshInterval = Key<Int>("refreshInterval", default: 5)
15+
static let cloudflaredProtocol = Key<CloudflaredProtocol>("cloudflaredProtocol", default: .http2)
1516

1617
// Kubernetes-related keys
1718
static let customNamespaces = Key<[String]>("customNamespaces", default: [])
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Defaults
2+
import Foundation
3+
4+
/// Supported transport protocols for cloudflared quick tunnels.
5+
enum CloudflaredProtocol: String, CaseIterable, Codable, Defaults.Serializable, Sendable {
6+
case http2 = "http2"
7+
case quic = "quic"
8+
9+
var displayName: String {
10+
switch self {
11+
case .http2: return "HTTP/2"
12+
case .quic: return "QUIC"
13+
}
14+
}
15+
}

platforms/macos/Sources/Services/CloudflaredService.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Foundation
22
import Darwin
3+
import Defaults
34

45
// MARK: - Cloudflared Service Actor
56

@@ -48,7 +49,8 @@ actor CloudflaredService {
4849

4950
let process = Process()
5051
process.executableURL = URL(fileURLWithPath: cloudflaredPath)
51-
process.arguments = ["tunnel", "--url", "localhost:\(port)"]
52+
let protocolValue = Defaults[.cloudflaredProtocol].rawValue
53+
process.arguments = ["tunnel", "--url", "localhost:\(port)", "--protocol", protocolValue]
5254

5355
let pipe = Pipe()
5456
process.standardOutput = pipe
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/// CloudflaredSettingsSection - Cloudflare tunnel preferences
2+
///
3+
/// Displays cloudflared settings including:
4+
/// - Transport protocol selection (HTTP/2 or QUIC)
5+
6+
import SwiftUI
7+
import Defaults
8+
9+
struct CloudflaredSettingsSection: View {
10+
@Default(.cloudflaredProtocol) private var protocolSelection
11+
12+
var body: some View {
13+
SettingsGroup("Cloudflare Tunnels", icon: "cloud.fill") {
14+
SettingsRowContainer {
15+
HStack {
16+
VStack(alignment: .leading, spacing: 2) {
17+
Text("Tunnel protocol")
18+
.fontWeight(.medium)
19+
Text("Choose how cloudflared connects to Cloudflare (applies to new tunnels)")
20+
.font(.caption)
21+
.foregroundStyle(.secondary)
22+
}
23+
24+
Spacer()
25+
26+
Picker("", selection: $protocolSelection) {
27+
ForEach(CloudflaredProtocol.allCases, id: \.self) { option in
28+
Text(option.displayName).tag(option)
29+
}
30+
}
31+
.labelsHidden()
32+
.pickerStyle(.segmented)
33+
.frame(width: 160)
34+
}
35+
}
36+
}
37+
}
38+
}

platforms/macos/Sources/Views/Settings/SettingsView.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ struct SettingsView: View {
3636
// MARK: - Port Forwarding
3737
PortForwardingSettingsSection()
3838

39+
// MARK: - Cloudflare Tunnels
40+
CloudflaredSettingsSection()
41+
3942
// MARK: - Keyboard Shortcuts
4043
ShortcutsSection()
4144

platforms/windows/PortKiller/App.xaml.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ private void ConfigureServices(IServiceCollection services)
4646
));
4747
services.AddSingleton<TunnelViewModel>(sp => new TunnelViewModel(
4848
sp.GetRequiredService<TunnelService>(),
49-
NotificationService.Instance
49+
NotificationService.Instance,
50+
sp.GetRequiredService<SettingsService>()
5051
));
5152
}
5253
}

platforms/windows/PortKiller/CloudflareTunnelsView.xaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,18 @@
9191
</StackPanel>
9292

9393
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
94+
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="0,0,12,0">
95+
<TextBlock Text="Protocol" FontSize="12" Foreground="#A0A0A0" VerticalAlignment="Center" Margin="0,0,8,0"/>
96+
<ComboBox Width="90"
97+
ItemsSource="{Binding ProtocolOptions}"
98+
SelectedValuePath="Value"
99+
SelectedValue="{Binding CloudflaredProtocol, Mode=TwoWay}"
100+
DisplayMemberPath="Label"
101+
Background="#3A3A3A"
102+
Foreground="#E0E0E0"
103+
BorderThickness="0"
104+
Padding="6,2"/>
105+
</StackPanel>
94106
<Button Content="Stop All"
95107
Click="StopAllButton_Click"
96108
Style="{StaticResource DangerButton}"

platforms/windows/PortKiller/MainWindow.xaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,19 @@
613613
<TextBlock Text="Cloudflare Tunnels" FontSize="20" FontWeight="SemiBold" Foreground="#E0E0E0"/>
614614
</StackPanel>
615615
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
616+
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="0,0,12,0">
617+
<TextBlock Text="Protocol" FontSize="12" Foreground="#A0A0A0" VerticalAlignment="Center" Margin="0,0,8,0"/>
618+
<ComboBox x:Name="TunnelProtocolCombo"
619+
Width="90"
620+
ItemsSource="{Binding ProtocolOptions}"
621+
SelectedValuePath="Value"
622+
SelectedValue="{Binding CloudflaredProtocol, Mode=TwoWay}"
623+
DisplayMemberPath="Label"
624+
Background="#3A3A3A"
625+
Foreground="#E0E0E0"
626+
BorderThickness="0"
627+
Padding="6,2"/>
628+
</StackPanel>
616629
<Button x:Name="StopAllTunnelsButton"
617630
Content="Stop All"
618631
Click="StopAllTunnels_Click"

platforms/windows/PortKiller/MainWindow.xaml.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public MainWindow()
2323

2424
_viewModel = App.Services.GetRequiredService<MainViewModel>();
2525
_tunnelViewModel = App.Services.GetRequiredService<TunnelViewModel>();
26+
TunnelProtocolCombo.DataContext = _tunnelViewModel;
2627
InitializeAsync();
2728

2829
// Setup keyboard shortcuts
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
namespace PortKiller.Models;
2+
3+
public enum CloudflaredProtocol
4+
{
5+
Http2,
6+
Quic
7+
}
8+
9+
public static class CloudflaredProtocolExtensions
10+
{
11+
public static string ToArgument(this CloudflaredProtocol protocol)
12+
{
13+
return protocol == CloudflaredProtocol.Quic ? "quic" : "http2";
14+
}
15+
16+
public static string ToDisplayName(this CloudflaredProtocol protocol)
17+
{
18+
return protocol == CloudflaredProtocol.Quic ? "QUIC" : "HTTP/2";
19+
}
20+
21+
public static CloudflaredProtocol FromString(string? value)
22+
{
23+
return string.Equals(value, "quic", System.StringComparison.OrdinalIgnoreCase)
24+
? CloudflaredProtocol.Quic
25+
: CloudflaredProtocol.Http2;
26+
}
27+
}

0 commit comments

Comments
 (0)