Skip to content

Commit e7a105a

Browse files
authored
Add proxy settings for Syncthing daemon (#283)
1 parent 89115d8 commit e7a105a

File tree

5 files changed

+135
-11
lines changed

5 files changed

+135
-11
lines changed

syncthing/Base.lproj/STPreferencesWindowGeneralView.xib

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,19 @@
88
<objects>
99
<customObject id="-2" userLabel="File's Owner" customClass="STPreferencesGeneralViewController">
1010
<connections>
11+
<outlet property="ProxyURL" destination="X8z-m3-H7F" id="Fn0-3o-LfW"/>
1112
<outlet property="StartAtLogin" destination="tYl-sb-Hga" id="nUj-DN-esv"/>
1213
<outlet property="Syncthing_ApiKey" destination="B0w-Uv-22O" id="DX5-97-308"/>
1314
<outlet property="Syncthing_URI" destination="kCf-gA-qTB" id="s6U-1e-YmN"/>
15+
<outlet property="UseProxy" destination="99B-Dd-LdB" id="2Eu-HJ-Wx6"/>
1416
<outlet property="buttonTest" destination="Fvn-Oe-6fA" id="gsg-wG-y69"/>
1517
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
1618
</connections>
1719
</customObject>
1820
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
1921
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
2022
<customView translatesAutoresizingMaskIntoConstraints="NO" id="Hz6-mo-xeY">
21-
<rect key="frame" x="0.0" y="0.0" width="457" height="190"/>
23+
<rect key="frame" x="0.0" y="0.0" width="457" height="248"/>
2224
<subviews>
2325
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SPp-6x-JiZ">
2426
<rect key="frame" x="18" y="121" width="49" height="16"/>
@@ -59,7 +61,7 @@
5961
</connections>
6062
</textField>
6163
<button translatesAutoresizingMaskIntoConstraints="NO" id="tYl-sb-Hga">
62-
<rect key="frame" x="71" y="81" width="104" height="18"/>
64+
<rect key="frame" x="71" y="139" width="104" height="18"/>
6365
<buttonCell key="cell" type="check" title="Start at login" bezelStyle="regularSquare" imagePosition="left" inset="2" id="bnF-et-LAz">
6466
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
6567
<font key="font" metaFont="system"/>
@@ -70,7 +72,7 @@
7072
</connections>
7173
</button>
7274
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Fvn-Oe-6fA">
73-
<rect key="frame" x="366" y="83" width="78" height="32"/>
75+
<rect key="frame" x="366" y="141" width="78" height="32"/>
7476
<buttonCell key="cell" type="push" title="Test" bezelStyle="rounded" image="NSStatusNone" imagePosition="left" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="DIH-Pb-tr4">
7577
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
7678
<font key="font" metaFont="system"/>
@@ -79,8 +81,47 @@
7981
<action selector="clickedTest:" target="-2" id="3Ta-ci-ddQ"/>
8082
</connections>
8183
</button>
84+
<button translatesAutoresizingMaskIntoConstraints="NO" id="99B-Dd-LdB">
85+
<rect key="frame" x="71" y="113" width="144" height="18"/>
86+
<buttonCell key="cell" type="check" title="Use proxy for Syncthing" bezelStyle="regularSquare" imagePosition="left" inset="2" id="Og8-oM-kqL">
87+
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
88+
<font key="font" metaFont="system"/>
89+
</buttonCell>
90+
<connections>
91+
<action selector="clickedUseProxy:" target="-2" id="Yrw-RK-eCY"/>
92+
<binding destination="43V-m6-OJJ" name="value" keyPath="values.UseProxy" id="NJQ-H5-yr9"/>
93+
</connections>
94+
</button>
95+
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="H6M-Xv-GvS">
96+
<rect key="frame" x="20" y="85" width="47" height="16"/>
97+
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Proxy" id="zcy-s6-PPy">
98+
<font key="font" metaFont="system"/>
99+
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
100+
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
101+
</textFieldCell>
102+
</textField>
103+
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="X8z-m3-H7F">
104+
<rect key="frame" x="73" y="82" width="364" height="21"/>
105+
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="socks5://127.0.0.1:7890" drawsBackground="YES" id="uUl-r5-Ao4">
106+
<font key="font" metaFont="system"/>
107+
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
108+
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
109+
</textFieldCell>
110+
<connections>
111+
<action selector="proxyUrlChanged:" target="-2" id="f2o-6n-2QY"/>
112+
<binding destination="43V-m6-OJJ" name="value" keyPath="values.ProxyURL" id="hoV-Fb-8mh"/>
113+
</connections>
114+
</textField>
115+
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="N0T-mL-rWn">
116+
<rect key="frame" x="73" y="56" width="364" height="17"/>
117+
<textFieldCell key="cell" lineBreakMode="byWordWrapping" sendsActionOnEndEditing="YES" title="Supports socks5://, http:// and https://. Changes restart the Syncthing daemon automatically." id="5k2-60-Pg8">
118+
<font key="font" metaFont="smallSystem"/>
119+
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
120+
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
121+
</textFieldCell>
122+
</textField>
82123
<button translatesAutoresizingMaskIntoConstraints="NO" id="aC0-rw-4G1">
83-
<rect key="frame" x="71" y="59" width="134" height="18"/>
124+
<rect key="frame" x="71" y="117" width="134" height="18"/>
84125
<buttonCell key="cell" type="check" title="Show in menu bar" bezelStyle="regularSquare" imagePosition="left" inset="2" id="nB8-OA-X1F">
85126
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
86127
<font key="font" metaFont="system"/>
@@ -124,7 +165,10 @@
124165
<constraint firstAttribute="trailing" secondItem="kCf-gA-qTB" secondAttribute="trailing" constant="20" symbolic="YES" id="0u5-rc-aQ9"/>
125166
<constraint firstItem="NQY-Se-yQr" firstAttribute="leading" secondItem="kCf-gA-qTB" secondAttribute="leading" id="1uy-lv-1dN"/>
126167
<constraint firstItem="kCf-gA-qTB" firstAttribute="leading" secondItem="bgQ-af-R3Y" secondAttribute="trailing" constant="8" symbolic="YES" id="2tE-WJ-egs"/>
127-
<constraint firstItem="tYl-sb-Hga" firstAttribute="top" secondItem="B0w-Uv-22O" secondAttribute="bottom" constant="20" id="8LG-LF-xbD"/>
168+
<constraint firstItem="99B-Dd-LdB" firstAttribute="leading" secondItem="kCf-gA-qTB" secondAttribute="leading" id="4Q7-8J-RWk"/>
169+
<constraint firstItem="99B-Dd-LdB" firstAttribute="top" secondItem="B0w-Uv-22O" secondAttribute="bottom" constant="20" id="4on-E6-7Oy"/>
170+
<constraint firstItem="H6M-Xv-GvS" firstAttribute="firstBaseline" secondItem="X8z-m3-H7F" secondAttribute="firstBaseline" id="53V-DK-e5P"/>
171+
<constraint firstItem="H6M-Xv-GvS" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="5v0-fM-wTn"/>
128172
<constraint firstAttribute="bottom" secondItem="NQY-Se-yQr" secondAttribute="bottom" constant="20" symbolic="YES" id="8n7-1W-VIF"/>
129173
<constraint firstAttribute="trailing" secondItem="9Rm-9W-VFZ" secondAttribute="trailing" constant="20" symbolic="YES" id="9SU-ES-8zG"/>
130174
<constraint firstItem="B0w-Uv-22O" firstAttribute="leading" secondItem="kCf-gA-qTB" secondAttribute="leading" id="BBg-3A-5eJ"/>
@@ -134,11 +178,18 @@
134178
<constraint firstItem="aC0-rw-4G1" firstAttribute="top" secondItem="tYl-sb-Hga" secondAttribute="bottom" constant="6" symbolic="YES" id="a2P-vl-xd1"/>
135179
<constraint firstItem="NQY-Se-yQr" firstAttribute="top" secondItem="aC0-rw-4G1" secondAttribute="bottom" constant="20" id="aF5-fX-MiH"/>
136180
<constraint firstItem="B0w-Uv-22O" firstAttribute="leading" secondItem="SPp-6x-JiZ" secondAttribute="trailing" constant="8" symbolic="YES" id="aks-Gy-fGL"/>
137-
<constraint firstItem="Fvn-Oe-6fA" firstAttribute="top" secondItem="B0w-Uv-22O" secondAttribute="bottom" constant="8" symbolic="YES" id="gjY-QU-9q1"/>
181+
<constraint firstItem="Fvn-Oe-6fA" firstAttribute="centerY" secondItem="tYl-sb-Hga" secondAttribute="centerY" id="gjY-QU-9q1"/>
182+
<constraint firstItem="X8z-m3-H7F" firstAttribute="leading" secondItem="H6M-Xv-GvS" secondAttribute="trailing" constant="8" symbolic="YES" id="gmb-yu-7Vu"/>
183+
<constraint firstAttribute="trailing" secondItem="X8z-m3-H7F" secondAttribute="trailing" constant="20" symbolic="YES" id="iK5-hP-XbW"/>
184+
<constraint firstItem="X8z-m3-H7F" firstAttribute="top" secondItem="99B-Dd-LdB" secondAttribute="bottom" constant="10" symbolic="YES" id="jY3-0n-8aP"/>
138185
<constraint firstAttribute="trailing" secondItem="B0w-Uv-22O" secondAttribute="trailing" constant="20" symbolic="YES" id="lWZ-ef-Ed2"/>
139186
<constraint firstItem="B0w-Uv-22O" firstAttribute="top" secondItem="kCf-gA-qTB" secondAttribute="bottom" constant="10" symbolic="YES" id="mg0-kD-bnu"/>
187+
<constraint firstItem="N0T-mL-rWn" firstAttribute="leading" secondItem="kCf-gA-qTB" secondAttribute="leading" id="nfs-eY-QdR"/>
188+
<constraint firstAttribute="trailing" secondItem="N0T-mL-rWn" secondAttribute="trailing" constant="20" symbolic="YES" id="uZa-6N-IxU"/>
189+
<constraint firstItem="N0T-mL-rWn" firstAttribute="top" secondItem="X8z-m3-H7F" secondAttribute="bottom" constant="8" symbolic="YES" id="upT-DS-vcQ"/>
140190
<constraint firstItem="bgQ-af-R3Y" firstAttribute="firstBaseline" secondItem="kCf-gA-qTB" secondAttribute="firstBaseline" id="r3e-1n-EcE"/>
141191
<constraint firstItem="tYl-sb-Hga" firstAttribute="leading" secondItem="kCf-gA-qTB" secondAttribute="leading" id="tVU-d6-WRW"/>
192+
<constraint firstItem="tYl-sb-Hga" firstAttribute="top" secondItem="N0T-mL-rWn" secondAttribute="bottom" constant="12" id="uMJ-HV-WQG"/>
142193
<constraint firstItem="9Rm-9W-VFZ" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="NQY-Se-yQr" secondAttribute="trailing" constant="7" id="ucj-yE-cmL"/>
143194
<constraint firstItem="SPp-6x-JiZ" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="20" symbolic="YES" id="udY-T2-UbN"/>
144195
<constraint firstItem="kCf-gA-qTB" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="20" symbolic="YES" id="xAJ-NF-i59"/>

syncthing/DaemonProcess.swift

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,44 @@ let MaxKeepLogLines = 200
3434
}
3535
}
3636

37+
private func launchEnvironment() -> [String: String] {
38+
var environment = ProcessInfo.processInfo.environment
39+
environment["STNOUPGRADE"] = "true"
40+
41+
let defaults = UserDefaults.standard
42+
if defaults.object(forKey: "UseProxy") != nil {
43+
let proxyURL = defaults.string(forKey: "ProxyURL")?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
44+
if defaults.bool(forKey: "UseProxy") && !proxyURL.isEmpty {
45+
environment["all_proxy"] = proxyURL
46+
environment["ALL_PROXY"] = proxyURL
47+
48+
let bypassHosts = "127.0.0.1,localhost"
49+
if let existing = environment["no_proxy"], !existing.isEmpty {
50+
if !existing.contains("127.0.0.1") || !existing.contains("localhost") {
51+
environment["no_proxy"] = "\(existing),\(bypassHosts)"
52+
}
53+
} else {
54+
environment["no_proxy"] = bypassHosts
55+
}
56+
57+
if let existing = environment["NO_PROXY"], !existing.isEmpty {
58+
if !existing.contains("127.0.0.1") || !existing.contains("localhost") {
59+
environment["NO_PROXY"] = "\(existing),\(bypassHosts)"
60+
}
61+
} else {
62+
environment["NO_PROXY"] = bypassHosts
63+
}
64+
} else {
65+
environment.removeValue(forKey: "all_proxy")
66+
environment.removeValue(forKey: "ALL_PROXY")
67+
environment.removeValue(forKey: "no_proxy")
68+
environment.removeValue(forKey: "NO_PROXY")
69+
}
70+
}
71+
72+
return environment
73+
}
74+
3775
@objc func launch() {
3876
queue.async {
3977
self.launchSync()
@@ -58,12 +96,8 @@ let MaxKeepLogLines = 200
5896
NSLog("Launching Syncthing daemon: \(path)")
5997
shouldTerminate = false
6098

61-
// Since release v1.7.0-1 we don't allow Syncthing daemon to update by itself
62-
var environment = ProcessInfo.processInfo.environment
63-
environment["STNOUPGRADE"] = "true"
64-
6599
let p = Process()
66-
p.environment = environment
100+
p.environment = launchEnvironment()
67101
p.arguments = ["--no-browser", "--no-restart", "--logfile=default"]
68102
p.arguments?.append(contentsOf: self.arguments)
69103
p.launchPath = path

syncthing/STApplication.m

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#import "STApplication.h"
22
#import "STLoginItem.h"
3+
#import "STPreferencesWindowGeneralViewController.h"
34
#import "Syncthing-Swift.h"
45

56
@interface STAppDelegate ()
@@ -30,6 +31,11 @@ @implementation STAppDelegate
3031
- (void) applicationDidFinishLaunching:(NSNotification *)aNotification {
3132
_syncthing = [[XGSyncthing alloc] init];
3233

34+
[[NSNotificationCenter defaultCenter] addObserver:self
35+
selector:@selector(proxySettingsDidChange:)
36+
name:STDaemonNeedsRestartNotification
37+
object:nil];
38+
3339
[self applicationLoadConfiguration];
3440

3541
_process = [[DaemonProcess alloc] initWithPath:_executable arguments: _arguments delegate:self];
@@ -129,6 +135,10 @@ - (void)applicationLoadConfiguration {
129135
if (![defaults objectForKey:@"StartAtLogin"]) {
130136
[defaults setBool:[STLoginItem wasAppAddedAsLoginItem] forKey:@"StartAtLogin"];
131137
}
138+
139+
if (![defaults objectForKey:@"ProxyURL"]) {
140+
[defaults setObject:@"" forKey:@"ProxyURL"];
141+
}
132142
}
133143

134144
- (void) sendNotification:(NSString *)text {
@@ -334,6 +344,12 @@ - (void)preferencesWillClose:(NSNotification *)notification {
334344
_preferencesWindow = nil;
335345
}
336346

347+
- (void)proxySettingsDidChange:(NSNotification *)notification {
348+
if (_process != nil) {
349+
[_process restart];
350+
}
351+
}
352+
337353
- (void)process:(DaemonProcess *)_ isRunning:(BOOL)isRunning {
338354
if (_daemonOK == isRunning) {
339355
return;

syncthing/STPreferencesWindowGeneralViewController.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010

1111
@interface STPreferencesWindowGeneralViewController : NSViewController
1212

13+
@property (weak) IBOutlet NSButton *UseProxy;
14+
@property (weak) IBOutlet NSTextField *ProxyURL;
1315
@property (weak) IBOutlet NSTextField *Syncthing_URI;
1416
@property (weak) IBOutlet NSTextField *Syncthing_ApiKey;
1517
@property (weak) IBOutlet NSButton *StartAtLogin;
1618
@property (weak) IBOutlet NSButton *buttonTest;
1719

20+
extern NSNotificationName const STDaemonNeedsRestartNotification;
1821

1922
@end

syncthing/STPreferencesWindowGeneralViewController.m

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#import "STLoginItem.h"
1111
#import "XGSyncthing.h"
1212

13+
NSNotificationName const STDaemonNeedsRestartNotification = @"STDaemonNeedsRestartNotification";
14+
1315
@interface STPreferencesWindowGeneralViewController ()
1416

1517
@end
@@ -18,6 +20,7 @@ @implementation STPreferencesWindowGeneralViewController
1820

1921
- (void) viewDidLoad {
2022
[super viewDidLoad];
23+
[self updateProxyControls];
2124
[self updateTestButton];
2225
}
2326

@@ -58,4 +61,21 @@ - (IBAction) clickedTest:(id)sender {
5861
[self updateTestButton];
5962
}
6063

64+
- (IBAction)clickedUseProxy:(id)sender {
65+
[self updateProxyControls];
66+
[self postDaemonRestartNotification];
67+
}
68+
69+
- (IBAction)proxyUrlChanged:(id)sender {
70+
[self postDaemonRestartNotification];
71+
}
72+
73+
- (void)postDaemonRestartNotification {
74+
[[NSNotificationCenter defaultCenter] postNotificationName:STDaemonNeedsRestartNotification object:self];
75+
}
76+
77+
- (void)updateProxyControls {
78+
[self.ProxyURL setEnabled:(self.UseProxy.state == NSControlStateValueOn)];
79+
}
80+
6181
@end

0 commit comments

Comments
 (0)