1 // godlighty -- highly-customizable HTTP, HTTP/2, HTTPS server
2 // Copyright (C) 2021-2024 Sergey Matveev <stargrave@stargrave.org>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, version 3 of the License.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program. If not, see <http://www.gnu.org/licenses/>.
32 "github.com/davecgh/go-spew/spew"
33 "golang.org/x/net/netutil"
35 "go.stargrave.org/godlighty"
36 _ "go.stargrave.org/godlighty/rc/cfg"
42 GracefulTime = 10 * time.Second
43 RWTimeout = 30 * time.Second
47 bind := flag.String("bind", "[::]:80", "Address to bind and listen on")
48 doTLS := flag.Bool("tls", false, "Enable TLS")
49 doSetUID := flag.Int("setuid", 0, "Set that UID after binding the socket")
50 doSetGID := flag.Int("setgid", 0, "Set that GID after binding the socket")
51 doSetGIDs := flag.String("setgids", "", "Comma-separated GIDs to set")
52 log.SetFlags(log.Lshortfile)
53 log.SetOutput(os.Stdout)
56 godlighty.LoadCertificates()
58 shutdown := make(chan os.Signal, 1)
59 signal.Notify(shutdown, syscall.SIGTERM, syscall.SIGINT, syscall.SIGHUP)
60 exitErr := make(chan error)
61 l, err := godlighty.DeadlinedListen("tcp", *bind, RWTimeout, RWTimeout)
67 if err := syscall.Setregid(*doSetGID, *doSetGID); err != nil {
73 if err := syscall.Setgroups([]int{*doSetGID}); err != nil {
79 for _, g := range strings.Split(*doSetGIDs, ",") {
80 gid, err := strconv.Atoi(g)
84 gids = append(gids, gid)
86 if err := syscall.Setgroups(gids); err != nil {
91 if err := syscall.Setreuid(*doSetUID, *doSetUID); err != nil {
96 info := make(chan os.Signal, 1)
97 signal.Notify(info, InfoSignal)
101 spew.Fdump(os.Stdout, godlighty.Hosts)
105 godlighty.BindAddr = *bind
107 Handler: godlighty.MainHandler,
108 ReadHeaderTimeout: RWTimeout,
109 IdleTimeout: time.Minute,
113 log.Println("shutting down")
114 ctx, cancel := context.WithTimeout(context.TODO(), GracefulTime)
115 exitErr <- srv.Shutdown(ctx)
120 tlsCfg := godlighty.NewTLSConfig()
121 ll = tls.NewListener(netutil.LimitListener(l, MaxConns), tlsCfg)
123 ll = netutil.LimitListener(l, MaxConns)
129 "hosts:", len(godlighty.Hosts),
131 if err = srv.Serve(ll); err != http.ErrServerClosed {
134 if err := <-exitErr; err != nil {