99
package CFG
import (
"fmt"
"net/http"
"os"
"strings"
)
var ConfFile = "/etc/manhttpd/manhttpd.conf"
type EtcConf struct {
Hostname string
Port string
Addr string
RequireAuth bool
PasswdFile string
TldrPages bool
EnableStats bool
StatisticDB string
}
var DefaultConf = EtcConf{
Hostname: "",
Port: "8082",
Addr: "0.0.0.0",
RequireAuth: false,
PasswdFile: "/etc/manhttpd/passwd",
TldrPages: false,
EnableStats: false,
StatisticDB: "/var/lib/manhttpd/stats.db",
}
func (c *EtcConf) Parse() error {
var mp = map[string]any{
"hostname": &(c.Hostname),
"port": &(c.Port),
"addr": &(c.Addr),
"require_auth": &(c.RequireAuth),
"passwd_file": &(c.PasswdFile),
"tldr_pages": &(c.TldrPages),
"enable_stats": &(c.EnableStats),
"statistic_db": &(c.StatisticDB),
}
b, err := os.ReadFile(ConfFile)
if err != nil {
return err
}
var j, k string
var kv []string
for _, v := range strings.Split(string(b), "\n") {
if len(v) == 0 || v[0] == '#' {
continue // skip empty lines and comments
}
kv = strings.SplitN(v, " ", 2)
if len(kv) != 2 {
return fmt.Errorf("invalid line in %s: %s", ConfFile, v)
}
k = strings.TrimSpace(kv[0])
j = strings.TrimSpace(kv[1])
if val, ok := mp[k]; ok {
switch v := val.(type) {
case *string:
*v = j
case *bool:
*v = j == "yes"
default:
return fmt.Errorf("unsupported type for key %s in %s", k, ConfFile)
}
} else {
return fmt.Errorf("unknown key %s in %s", k, ConfFile)
}
}
return nil
}
func ParseEtcConf() (EtcConf, error) {
c := DefaultConf
if err := c.Parse(); err != nil {
return c, fmt.Errorf("failed to parse %s: %w", ConfFile, err)
}
if c.Port == "" {
c.Port = "8082"
}
if c.Addr == "" {
c.Addr = "0.0.0.0"
}
if c.Hostname != "" {
Hostname = c.Hostname
}
return c, nil
}
func (c *EtcConf) Server(h http.Handler) *http.Server {
return &http.Server{
Addr: c.Addr + ":" + c.Port,
Handler: h,
}
}