Browse Source

Add initial support for unix sockets (#2852)

Odin Ugedal 8 years ago
parent
commit
1dd003bd4c
3 changed files with 44 additions and 13 deletions
  1. 18 0
      cmd/web.go
  2. 2 0
      conf/app.ini
  3. 24 13
      modules/setting/setting.go

+ 18 - 0
cmd/web.go

@@ -8,6 +8,7 @@ import (
 	"crypto/tls"
 	"fmt"
 	"io/ioutil"
+	"net"
 	"net/http"
 	"net/http/fcgi"
 	"os"
@@ -582,6 +583,9 @@ func runWeb(ctx *cli.Context) error {
 
 	var err error
 	listenAddr := fmt.Sprintf("%s:%s", setting.HttpAddr, setting.HttpPort)
+	if setting.Protocol == setting.UNIX_SOCKET {
+		listenAddr = fmt.Sprintf("%s", setting.HttpAddr)
+	}
 	log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubUrl)
 	switch setting.Protocol {
 	case setting.HTTP:
@@ -591,6 +595,20 @@ func runWeb(ctx *cli.Context) error {
 		err = server.ListenAndServeTLS(setting.CertFile, setting.KeyFile)
 	case setting.FCGI:
 		err = fcgi.Serve(nil, m)
+	case setting.UNIX_SOCKET:
+		os.Remove(listenAddr)
+		listener, err := net.ListenUnix("unix", &net.UnixAddr{listenAddr, "unix"})
+		if err != nil {
+			break
+		}
+		// FIXME add proper implementation of signal capture on all protocols
+		// execute this on SIGTERM or SIGINT: listener.Close()
+		err = os.Chmod(listenAddr, os.FileMode(setting.UnixSocketPermission))
+		if err != nil {
+			log.Fatal(4, "Failed to set permission of unix socket: %v", err)
+		}
+		err = http.Serve(listener, m)
+
 	default:
 		log.Fatal(4, "Invalid protocol: %s", setting.Protocol)
 	}

+ 2 - 0
conf/app.ini

@@ -61,6 +61,8 @@ DOMAIN = localhost
 ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/
 HTTP_ADDR = 0.0.0.0
 HTTP_PORT = 3000
+; Permission for unix socket
+UNIX_SOCKET_PERMISSION = 666
 ; Local (DMZ) URL for Gogs workers (such as SSH update) accessing web service.
 ; In most cases you do not need to change the default value.
 ; Alter it only if your SSH server node is not the same as HTTP node.

+ 24 - 13
modules/setting/setting.go

@@ -12,6 +12,7 @@ import (
 	"path"
 	"path/filepath"
 	"runtime"
+	"strconv"
 	"strings"
 	"time"
 
@@ -31,9 +32,10 @@ import (
 type Scheme string
 
 const (
-	HTTP  Scheme = "http"
-	HTTPS Scheme = "https"
-	FCGI  Scheme = "fcgi"
+	HTTP        Scheme = "http"
+	HTTPS       Scheme = "https"
+	FCGI        Scheme = "fcgi"
+	UNIX_SOCKET Scheme = "unix"
 )
 
 type LandingPage string
@@ -58,16 +60,17 @@ var (
 	AppDataPath    string
 
 	// Server settings
-	Protocol           Scheme
-	Domain             string
-	HttpAddr, HttpPort string
-	LocalURL           string
-	OfflineMode        bool
-	DisableRouterLog   bool
-	CertFile, KeyFile  string
-	StaticRootPath     string
-	EnableGzip         bool
-	LandingPageUrl     LandingPage
+	Protocol             Scheme
+	Domain               string
+	HttpAddr, HttpPort   string
+	LocalURL             string
+	OfflineMode          bool
+	DisableRouterLog     bool
+	CertFile, KeyFile    string
+	StaticRootPath       string
+	EnableGzip           bool
+	LandingPageUrl       LandingPage
+	UnixSocketPermission uint32
 
 	SSH struct {
 		Disabled            bool           `ini:"DISABLE_SSH"`
@@ -367,11 +370,19 @@ func NewContext() {
 		KeyFile = sec.Key("KEY_FILE").String()
 	} else if sec.Key("PROTOCOL").String() == "fcgi" {
 		Protocol = FCGI
+	} else if sec.Key("PROTOCOL").String() == "unix" {
+		Protocol = UNIX_SOCKET
 	}
 	Domain = sec.Key("DOMAIN").MustString("localhost")
 	HttpAddr = sec.Key("HTTP_ADDR").MustString("0.0.0.0")
 	HttpPort = sec.Key("HTTP_PORT").MustString("3000")
 	LocalURL = sec.Key("LOCAL_ROOT_URL").MustString(string(Protocol) + "://localhost:" + HttpPort + "/")
+	UnixSocketPermissionRaw := sec.Key("UNIX_SOCKET_PERMISSION").MustString("666")
+	UnixSocketPermissionParsed, err := strconv.ParseUint(UnixSocketPermissionRaw, 8, 32)
+	if err != nil || UnixSocketPermissionParsed > 0777 {
+		log.Fatal(4, "Fail to parse unixSocketPermission: %s", UnixSocketPermissionRaw)
+	}
+	UnixSocketPermission = uint32(UnixSocketPermissionParsed)
 	OfflineMode = sec.Key("OFFLINE_MODE").MustBool()
 	DisableRouterLog = sec.Key("DISABLE_ROUTER_LOG").MustBool()
 	StaticRootPath = sec.Key("STATIC_ROOT_PATH").MustString(workDir)