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