Create CLI option to bind to UNIX socket (#265)
This commit is contained in:
parent
9d693c93a3
commit
966711019b
|
@ -8,6 +8,7 @@ import (
|
||||||
var Flags struct {
|
var Flags struct {
|
||||||
HttpHost string
|
HttpHost string
|
||||||
HttpPort string
|
HttpPort string
|
||||||
|
HttpSock string
|
||||||
MaxSize int64
|
MaxSize int64
|
||||||
UploadDir string
|
UploadDir string
|
||||||
StoreSize int64
|
StoreSize int64
|
||||||
|
@ -33,6 +34,7 @@ var Flags struct {
|
||||||
func ParseFlags() {
|
func ParseFlags() {
|
||||||
flag.StringVar(&Flags.HttpHost, "host", "0.0.0.0", "Host to bind HTTP server to")
|
flag.StringVar(&Flags.HttpHost, "host", "0.0.0.0", "Host to bind HTTP server to")
|
||||||
flag.StringVar(&Flags.HttpPort, "port", "1080", "Port to bind HTTP server to")
|
flag.StringVar(&Flags.HttpPort, "port", "1080", "Port to bind HTTP server to")
|
||||||
|
flag.StringVar(&Flags.HttpSock, "unix-sock", "", "If set, will listen to a UNIX socket at this location instead of a TCP socket")
|
||||||
flag.Int64Var(&Flags.MaxSize, "max-size", 0, "Maximum size of a single upload in bytes")
|
flag.Int64Var(&Flags.MaxSize, "max-size", 0, "Maximum size of a single upload in bytes")
|
||||||
flag.StringVar(&Flags.UploadDir, "dir", "./data", "Directory to store uploads in")
|
flag.StringVar(&Flags.UploadDir, "dir", "./data", "Directory to store uploads in")
|
||||||
flag.Int64Var(&Flags.StoreSize, "store-size", 0, "Size of space allowed for storage")
|
flag.Int64Var(&Flags.StoreSize, "store-size", 0, "Size of space allowed for storage")
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -98,3 +100,40 @@ func NewListener(addr string, readTimeout, writeTimeout time.Duration) (net.List
|
||||||
}
|
}
|
||||||
return tl, nil
|
return tl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Binds to a UNIX socket. If the file already exists, try to remove it before
|
||||||
|
// binding again. This logic is borrowed from Gunicorn
|
||||||
|
// (see https://github.com/benoitc/gunicorn/blob/a8963ef1a5a76f3df75ce477b55fe0297e3b617d/gunicorn/sock.py#L106)
|
||||||
|
func NewUnixListener(path string, readTimeout, writeTimeout time.Duration) (net.Listener, error) {
|
||||||
|
stat, err := os.Stat(path)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if !os.IsNotExist(err) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if stat.Mode()&os.ModeSocket != 0 {
|
||||||
|
err = os.Remove(path)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("specified path is not a socket")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
l, err := net.Listen("unix", path)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tl := &Listener{
|
||||||
|
Listener: l,
|
||||||
|
ReadTimeout: readTimeout,
|
||||||
|
WriteTimeout: writeTimeout,
|
||||||
|
}
|
||||||
|
|
||||||
|
return tl, nil
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +1,19 @@
|
||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/tus/tusd"
|
"github.com/tus/tusd"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Setups the different components, starts a Listener and give it to
|
||||||
|
// http.Serve().
|
||||||
|
//
|
||||||
|
// By default it will bind to the specified host/port, unless a UNIX socket is
|
||||||
|
// specified, in which case a different socket creation and binding mechanism
|
||||||
|
// is put in place.
|
||||||
func Serve() {
|
func Serve() {
|
||||||
SetupPreHooks(Composer)
|
SetupPreHooks(Composer)
|
||||||
|
|
||||||
|
@ -24,10 +31,17 @@ func Serve() {
|
||||||
stderr.Fatalf("Unable to create handler: %s", err)
|
stderr.Fatalf("Unable to create handler: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
address := Flags.HttpHost + ":" + Flags.HttpPort
|
|
||||||
basepath := Flags.Basepath
|
basepath := Flags.Basepath
|
||||||
|
address := ""
|
||||||
|
|
||||||
|
if Flags.HttpSock != "" {
|
||||||
|
address = Flags.HttpSock
|
||||||
|
stdout.Printf("Using %s as socket to listen.\n", address)
|
||||||
|
} else {
|
||||||
|
address = Flags.HttpHost + ":" + Flags.HttpPort
|
||||||
stdout.Printf("Using %s as address to listen.\n", address)
|
stdout.Printf("Using %s as address to listen.\n", address)
|
||||||
|
}
|
||||||
|
|
||||||
stdout.Printf("Using %s as the base path.\n", basepath)
|
stdout.Printf("Using %s as the base path.\n", basepath)
|
||||||
|
|
||||||
SetupPostHooks(handler)
|
SetupPostHooks(handler)
|
||||||
|
@ -47,8 +61,15 @@ func Serve() {
|
||||||
|
|
||||||
http.Handle(basepath, http.StripPrefix(basepath, handler))
|
http.Handle(basepath, http.StripPrefix(basepath, handler))
|
||||||
|
|
||||||
|
var listener net.Listener
|
||||||
timeoutDuration := time.Duration(Flags.Timeout) * time.Millisecond
|
timeoutDuration := time.Duration(Flags.Timeout) * time.Millisecond
|
||||||
listener, err := NewListener(address, timeoutDuration, timeoutDuration)
|
|
||||||
|
if Flags.HttpSock != "" {
|
||||||
|
listener, err = NewUnixListener(address, timeoutDuration, timeoutDuration)
|
||||||
|
} else {
|
||||||
|
listener, err = NewListener(address, timeoutDuration, timeoutDuration)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
stderr.Fatalf("Unable to create listener: %s", err)
|
stderr.Fatalf("Unable to create listener: %s", err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue