about summary refs log tree commit diff
path: root/main.go
diff options
context:
space:
mode:
authorV <v@anomalous.eu>2021-08-27 06:08:09 +0200
committerV <v@anomalous.eu>2021-08-27 06:08:09 +0200
commitd49fe57776e6d19181c8ccb8d5332ed2c62d5ca8 (patch)
treee3036d32e318bfaef519c316de7e7f44b9351fef /main.go
downloadloxy-0.2.0.tar.zst
Root commit HEAD v0.2.0 trunk
Co-authored-by: edef <edef@edef.eu>
Diffstat (limited to 'main.go')
-rw-r--r--main.go94
1 files changed, 94 insertions, 0 deletions
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..5b5f617
--- /dev/null
+++ b/main.go
@@ -0,0 +1,94 @@
+// SPDX-FileCopyrightText: V <v@anomalous.eu>
+// SPDX-FileCopyrightText: edef <edef@edef.eu>
+// SPDX-License-Identifier: OSL-3.0
+
+package main // import "go.anomalous.eu/loxy"
+
+import (
+	"context"
+	"crypto/tls"
+	"flag"
+	"io/ioutil"
+	"log"
+	"net"
+	"net/http"
+	"os"
+	"os/signal"
+	"syscall"
+)
+
+var dbpath, certpath string
+var addr interface {
+	flag.Value
+	Listeners() ([]net.Listener, error)
+}
+
+func init() {
+	if os.Getenv("LISTEN_FDS") == "" {
+		a := listenAddress(net.JoinHostPort("::1", "3893"))
+		addr = &a
+	} else {
+		addr = activationSocket{}
+	}
+
+	flag.Var(addr, "addr", "listen address")
+	flag.StringVar(&dbpath, "db", "loxy.db", "`path` to database")
+	flag.StringVar(&certpath, "cert", "", "`path` to client certificate")
+	log.SetFlags(log.Lshortfile)
+}
+
+func main() {
+	flag.Parse()
+	if flag.NArg() != 0 {
+		flag.Usage()
+		os.Exit(1)
+	}
+
+	tlsConfig := &tls.Config{}
+	if certpath != "" {
+		pem, err := ioutil.ReadFile(certpath)
+		if err != nil {
+			log.Fatal(err)
+		}
+
+		cert, err := tls.X509KeyPair(pem, pem)
+		if err != nil {
+			log.Fatal(err)
+		}
+
+		tlsConfig.Certificates = []tls.Certificate{cert}
+	}
+
+	proxy := NewProxy(OpenStore(dbpath), tlsConfig)
+	server := &http.Server{Handler: proxy}
+
+	ctx, cancel := context.WithCancel(context.Background())
+	server.BaseContext = func(net.Listener) context.Context { return ctx }
+	server.RegisterOnShutdown(cancel)
+
+	sig := make(chan os.Signal, 1)
+	signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
+
+	listeners, err := addr.Listeners()
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	serve := make(chan error, len(listeners))
+	for _, ln := range listeners {
+		go func(ln net.Listener) { serve <- server.Serve(ln) }(ln)
+	}
+
+	select {
+	case err = <-serve:
+		log.Printf("http.ListenAndServe: %v", err)
+	case sig := <-sig:
+		log.Printf("caught %v, shutting down", sig)
+		server.Shutdown(context.Background())
+	}
+	proxy.Shutdown()
+
+	if err != nil {
+		os.Exit(1)
+	}
+}