Skip to content

Commit

Permalink
Allow listening on a Unix Domain Socket
Browse files Browse the repository at this point in the history
  • Loading branch information
matvore committed Jan 2, 2023
1 parent 334a9ec commit 05eb3ad
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 16 deletions.
14 changes: 10 additions & 4 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (

type Config struct {
Addr []string // TCP addresses to listen on. e.g. ":1234", "1.2.3.4:1234" or "[::1]:1234"
Uds string // Unix Domain Socket to listen on
MaxForks int // Number of allowable concurrent forks
LogLevel libwebsocketd.LogLevel
RedirPort int
Expand Down Expand Up @@ -65,6 +66,7 @@ func parseCommandLine() *Config {

// server config options
portFlag := flag.Int("port", 0, "HTTP port to listen on")
udsFlag := flag.String("uds", "", "Path of the Unix Domain Socket to listen on")
versionFlag := flag.Bool("version", false, "Print version and exit")
licenseFlag := flag.Bool("license", false, "Print license and exit")
logLevelFlag := flag.String("loglevel", "access", "Log level, one of: debug, trace, access, info, error, fatal")
Expand Down Expand Up @@ -104,23 +106,27 @@ func parseCommandLine() *Config {
}
}

ipSocknum := len(addrlist)
port := *portFlag
if port == 0 {
udsOnly := *udsFlag != "" && ipSocknum == 0 && port == 0 && *redirPortFlag == 0

if port == 0 && !udsOnly {
if *sslFlag {
port = 443
} else {
port = 80
}
}

if socknum := len(addrlist); socknum != 0 {
mainConfig.Addr = make([]string, socknum)
if ipSocknum != 0 {
mainConfig.Addr = make([]string, ipSocknum)
for i, addrSingle := range addrlist {
mainConfig.Addr[i] = fmt.Sprintf("%s:%d", addrSingle, port)
}
} else {
} else if !udsOnly {
mainConfig.Addr = []string{fmt.Sprintf(":%d", port)}
}
mainConfig.Uds = *udsFlag
mainConfig.MaxForks = *maxForksFlag
mainConfig.RedirPort = *redirPortFlag
mainConfig.LogLevel = libwebsocketd.LevelFromString(*logLevelFlag)
Expand Down
5 changes: 5 additions & 0 deletions help.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ Options:
Use square brackets to specify IPv6 address.
Default: "" (all)
--uds=PATH Path to create a Unix Domain Socket to listen
on. If this is specified and no IP-specific
flags are specified, do not listen on IP.
Default: "" (do not serve on UDS)
--sameorigin={true,false} Restrict (HTTP 403) protocol upgrades if the
Origin header does not match to requested HTTP
Host. Default: false.
Expand Down
3 changes: 2 additions & 1 deletion libwebsocketd/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ func NewWebsocketdHandler(s *WebsocketdServer, req *http.Request, log *LogScope)

wsh.RemoteInfo, err = GetRemoteInfo(req.RemoteAddr, s.Config.ReverseLookup)
if err != nil {
// This occurs when serving over Unix Domain Sockets.
log.Error("session", "Could not understand remote address '%s': %s", req.RemoteAddr, err)
return nil, err
wsh.RemoteInfo = &RemoteInfo{Addr: "unknown_host", Host: "unknown_host", Port: ""}
}
log.Associate("remote", wsh.RemoteInfo.Host)

Expand Down
31 changes: 20 additions & 11 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package main

import (
"fmt"
"net"
"net/http"
"os"
"runtime"
Expand Down Expand Up @@ -70,24 +71,28 @@ func main() {
}

rejects := make(chan error, 1)

// Serve and ServeTLS, called by the serve function below, do not return
// except on error. Let's run serve in a go routine, reporting result to
// control channel. This allows us to have multiple serve addresses.
serve := func(network, address string) {
if listener, err := net.Listen(network, address); err != nil {
rejects <- err
} else if config.Ssl {
rejects <- http.ServeTLS(listener, nil, config.CertFile, config.KeyFile)
} else {
rejects <- http.Serve(listener, nil)
}
}

for _, addrSingle := range config.Addr {
log.Info("server", "Starting WebSocket server : %s", handler.TellURL("ws", addrSingle, "/"))
if config.DevConsole {
log.Info("server", "Developer console enabled : %s", handler.TellURL("http", addrSingle, "/"))
} else if config.StaticDir != "" || config.CgiDir != "" {
log.Info("server", "Serving CGI or static files : %s", handler.TellURL("http", addrSingle, "/"))
}
// ListenAndServe is blocking function. Let's run it in
// go routine, reporting result to control channel.
// Since it's blocking it'll never return non-error.

go func(addr string) {
if config.Ssl {
rejects <- http.ListenAndServeTLS(addr, config.CertFile, config.KeyFile, nil)
} else {
rejects <- http.ListenAndServe(addr, nil)
}
}(addrSingle)
go serve("tcp", addrSingle)

if config.RedirPort != 0 {
go func(addr string) {
Expand All @@ -112,6 +117,10 @@ func main() {
}(addrSingle)
}
}
if config.Uds != "" {
log.Info("server", "Starting WebSocket server on Unix Domain Socket: %s", config.Uds)
go serve("unix", config.Uds)
}
err := <-rejects
if err != nil {
log.Fatal("server", "Can't start server: %s", err)
Expand Down

0 comments on commit 05eb3ad

Please sign in to comment.