soju/config/config.go

119 lines
2.3 KiB
Go
Raw Normal View History

2020-02-18 13:10:23 +00:00
package config
import (
"fmt"
"net"
2020-02-18 13:10:23 +00:00
"os"
"git.sr.ht/~emersion/go-scfg"
2020-02-18 13:10:23 +00:00
)
type IPSet []*net.IPNet
func (set IPSet) Contains(ip net.IP) bool {
for _, n := range set {
if n.Contains(ip) {
return true
}
}
return false
}
// loopbackIPs contains the loopback networks 127.0.0.0/8 and ::1/128.
var loopbackIPs = IPSet{
&net.IPNet{
IP: net.IP{127, 0, 0, 0},
Mask: net.CIDRMask(8, 32),
},
&net.IPNet{
IP: net.IPv6loopback,
Mask: net.CIDRMask(128, 128),
},
}
2020-02-18 13:10:23 +00:00
type TLS struct {
CertPath, KeyPath string
}
type Server struct {
Listen []string
Hostname string
TLS *TLS
SQLDriver string
SQLSource string
LogPath string
HTTPOrigins []string
AcceptProxyIPs IPSet
2020-02-18 13:10:23 +00:00
}
func Defaults() *Server {
hostname, err := os.Hostname()
if err != nil {
hostname = "localhost"
}
return &Server{
Hostname: hostname,
SQLDriver: "sqlite3",
SQLSource: "soju.db",
2020-02-18 13:10:23 +00:00
}
}
func Load(path string) (*Server, error) {
cfg, err := scfg.Load(path)
2020-02-18 13:10:23 +00:00
if err != nil {
return nil, err
}
return parse(cfg)
2020-02-18 13:10:23 +00:00
}
func parse(cfg scfg.Block) (*Server, error) {
2020-02-18 13:10:23 +00:00
srv := Defaults()
for _, d := range cfg {
2020-02-18 13:10:23 +00:00
switch d.Name {
case "listen":
var uri string
if err := d.ParseParams(&uri); err != nil {
2020-02-18 13:10:23 +00:00
return nil, err
}
srv.Listen = append(srv.Listen, uri)
2020-02-18 13:10:23 +00:00
case "hostname":
if err := d.ParseParams(&srv.Hostname); err != nil {
2020-02-18 13:10:23 +00:00
return nil, err
}
case "tls":
tls := &TLS{}
if err := d.ParseParams(&tls.CertPath, &tls.KeyPath); err != nil {
2020-02-18 13:10:23 +00:00
return nil, err
}
srv.TLS = tls
case "sql":
if err := d.ParseParams(&srv.SQLDriver, &srv.SQLSource); err != nil {
return nil, err
}
case "log":
if err := d.ParseParams(&srv.LogPath); err != nil {
return nil, err
}
case "http-origin":
srv.HTTPOrigins = d.Params
case "accept-proxy-ip":
srv.AcceptProxyIPs = nil
for _, s := range d.Params {
if s == "localhost" {
srv.AcceptProxyIPs = append(srv.AcceptProxyIPs, loopbackIPs...)
continue
}
_, n, err := net.ParseCIDR(s)
if err != nil {
return nil, fmt.Errorf("directive %q: failed to parse CIDR: %v", d.Name, err)
}
srv.AcceptProxyIPs = append(srv.AcceptProxyIPs, n)
}
2020-02-18 13:10:23 +00:00
default:
return nil, fmt.Errorf("unknown directive %q", d.Name)
}
}
return srv, nil
}