summaryrefslogtreecommitdiff
path: root/main.go
blob: 4781376ce3bd475f4144c60d93cceb9a0832edc9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// Copyright 2022 Terin Stock.
// SPDX-License-Identifier: MPL-2.0

package main

import (
	"context"
	"flag"
	"log/slog"
	"net"
	"net/http"
	"net/http/pprof"
	"os"
	"os/signal"
	"strconv"
	"time"

	"github.com/gorilla/mux"
	"go.terinstock.com/cgit-httpd/handlers/cgit"
	"go.terinstock.com/cgit-httpd/handlers/git"
	"go.terinstock.com/cgit-httpd/manager"
	"go.terinstock.com/cgit-httpd/server"
)

var configFile string

func main() {
	flag.StringVar(&configFile, "config", "./config.edn", "path to cgit-httpd configuration file")
	flag.Parse()

	logger := slog.New(slog.NewTextHandler(os.Stderr, nil))
	slog.SetDefault(logger)

	cfg, err := readConfig(configFile)
	if err != nil {
		logger.Error("could not parse config", "error", err)
		os.Exit(1)
	}

	logger.Info("", "config", cfg)

	gitMux := mux.NewRouter()

	git.New(git.Options{
		CGI:       cfg.Git.CGI,
		ReposRoot: cfg.ReposRoot,
		ExportAll: cfg.Git.ExportAll,
		Logger:    logger.With("handler", "git"),
	}).
		WithRegister(RegistererFunc(gitMux.Handle)).
		Build()

	cgit.New(cgit.Options{
		CGI:        cfg.CGit.CGI,
		ReposRoot:  cfg.ReposRoot,
		AssetsDir:  cfg.CGit.AssetsDir,
		ConfigFile: cfg.CGit.ConfigFile,
		Logger:     logger.With("handler", "cgit"),
	}).
		WithRegister(RegistererFunc(gitMux.Handle)).
		Build()

	m := manager.New()
	m.Add(&server.Server{
		Name: "git",
		Server: &http.Server{
			Addr:              net.JoinHostPort(cfg.HTTP.Host, strconv.Itoa(cfg.HTTP.Port)),
			Handler:           gitMux,
			MaxHeaderBytes:    1 << 20,
			IdleTimeout:       90 * time.Second,
			ReadHeaderTimeout: 32 * time.Second,
		},
	})

	if cfg.Pprof.Port != 0 {
		mux := http.NewServeMux()

		mux.HandleFunc("/debug/pprof/", pprof.Index)
		mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
		mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
		mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
		mux.HandleFunc("/debug/pprof/trace", pprof.Trace)

		m.Add(&server.Server{
			Name: "pprof",
			Server: &http.Server{
				Addr:    net.JoinHostPort(cfg.Pprof.Host, strconv.Itoa(cfg.Pprof.Port)),
				Handler: mux,
			},
		})
	}

	ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
	defer cancel()
	if err := m.Start(ctx); err != nil {
		logger.Info("manager stopped", "error", err)
	}
}

type RegistererFunc func(string, http.Handler) *mux.Route

func (r RegistererFunc) Register(name string, handler http.Handler) {
	r(name, handler)
}