소스 검색

cmd/syncthing: Listen on UNIX socket (fixes #3616) (#5210)

This adds the ability to listen on (only) a UNIX socket.
Jakob Borg 7 년 전
부모
커밋
5a69e85e80
3개의 변경된 파일50개의 추가작업 그리고 4개의 파일을 삭제
  1. 11 1
      cmd/syncthing/gui.go
  2. 5 1
      gui/default/syncthing/settings/settingsModalView.html
  3. 34 2
      lib/config/guiconfiguration.go

+ 11 - 1
cmd/syncthing/gui.go

@@ -206,7 +206,13 @@ func (s *apiService) getListener(guiCfg config.GUIConfiguration) (net.Listener,
 		},
 	}
 
-	rawListener, err := net.Listen("tcp", guiCfg.Address())
+	if guiCfg.Network() == "unix" {
+		// When listening on a UNIX socket we should unlink before bind,
+		// lest we get a "bind: address already in use". We don't
+		// particularly care if this succeeds or not.
+		os.Remove(guiCfg.Address())
+	}
+	rawListener, err := net.Listen(guiCfg.Network(), guiCfg.Address())
 	if err != nil {
 		return nil, err
 	}
@@ -420,6 +426,9 @@ func (s *apiService) String() string {
 }
 
 func (s *apiService) VerifyConfiguration(from, to config.Configuration) error {
+	if to.GUI.Network() != "tcp" {
+		return nil
+	}
 	_, err := net.ResolveTCPAddr("tcp", to.GUI.Address())
 	return err
 }
@@ -980,6 +989,7 @@ func (s *apiService) getSystemStatus(w http.ResponseWriter, r *http.Request) {
 	res["urVersionMax"] = usageReportVersion
 	res["uptime"] = int(time.Since(startTime).Seconds())
 	res["startTime"] = startTime
+	res["guiAddressOverridden"] = s.cfg.GUI().IsOverridden()
 
 	sendJSON(w, res)
 }

+ 5 - 1
gui/default/syncthing/settings/settingsModalView.html

@@ -111,7 +111,11 @@
         <div id="settings-gui" class="tab-pane">
           <div class="form-group"  ng-class="{'has-error': settingsEditor.Address.$invalid && settingsEditor.Address.$dirty}">
             <label translate for="Address">GUI Listen Address</label>&emsp;<a href="https://docs.syncthing.net/users/guilisten.html" target="_blank"><span class="fas fa-question-circle"></span>&nbsp;<span translate>Help</span></a>
-            <input id="Address" name="Address" class="form-control" type="text" ng-model="tmpGUI.address" ng-pattern="/.*:0*((102[4-9])|(10[3-9][0-9])|(1[1-9][0-9][0-9])|([2-9][0-9][0-9][0-9])|([1-6]\d{4}))$/"/>
+            <p class="text-warning" ng-show="system.guiAddressOverridden">
+                <span class="fas fa-exclamation-triangle"></span>
+                <span translate>The GUI address is overridden by startup options. Changes here will not take effect while the override is in place.</span>
+            </p>
+            <input id="Address" name="Address" class="form-control" type="text" ng-model="tmpGUI.address" ng-pattern="/^(/.*)|(.*:0*((102[4-9])|(10[3-9][0-9])|(1[1-9][0-9][0-9])|([2-9][0-9][0-9][0-9])|([1-6]\d{4})))$/"/>
               <p class="help-block" ng-show="settingsEditor.Address.$invalid" translate>
                 Enter a non-privileged port number (1024 - 65535).
               </p>

+ 34 - 2
lib/config/guiconfiguration.go

@@ -31,6 +31,10 @@ func (c GUIConfiguration) IsAuthEnabled() bool {
 	return c.AuthMode == AuthModeLDAP || (len(c.User) > 0 && len(c.Password) > 0)
 }
 
+func (c GUIConfiguration) IsOverridden() bool {
+	return os.Getenv("STGUIADDRESS") != ""
+}
+
 func (c GUIConfiguration) Address() string {
 	if override := os.Getenv("STGUIADDRESS"); override != "" {
 		// This value may be of the form "scheme://address:port" or just
@@ -43,6 +47,9 @@ func (c GUIConfiguration) Address() string {
 			if err != nil {
 				return override
 			}
+			if strings.HasPrefix(url.Scheme, "unix") {
+				return url.Path
+			}
 			return url.Host
 		}
 
@@ -52,14 +59,39 @@ func (c GUIConfiguration) Address() string {
 	return c.RawAddress
 }
 
+func (c GUIConfiguration) Network() string {
+	if override := os.Getenv("STGUIADDRESS"); strings.Contains(override, "/") {
+		url, err := url.Parse(override)
+		if err != nil {
+			return "tcp"
+		}
+		if strings.HasPrefix(url.Scheme, "unix") {
+			return "unix"
+		}
+	}
+	if strings.HasPrefix(c.RawAddress, "/") {
+		return "unix"
+	}
+	return "tcp"
+}
+
 func (c GUIConfiguration) UseTLS() bool {
-	if override := os.Getenv("STGUIADDRESS"); override != "" && strings.HasPrefix(override, "http") {
-		return strings.HasPrefix(override, "https:")
+	if override := os.Getenv("STGUIADDRESS"); override != "" {
+		if strings.HasPrefix(override, "http") {
+			return strings.HasPrefix(override, "https:")
+		}
+		if strings.HasPrefix(override, "unix") {
+			return strings.HasPrefix(override, "unixs:")
+		}
 	}
 	return c.RawUseTLS
 }
 
 func (c GUIConfiguration) URL() string {
+	if strings.HasPrefix(c.RawAddress, "/") {
+		return "unix://" + c.RawAddress
+	}
+
 	u := url.URL{
 		Scheme: "http",
 		Host:   c.Address(),