summaryrefslogtreecommitdiffstats
path: root/roseh.moe.go
diff options
context:
space:
mode:
Diffstat (limited to 'roseh.moe.go')
-rw-r--r--roseh.moe.go114
1 files changed, 91 insertions, 23 deletions
diff --git a/roseh.moe.go b/roseh.moe.go
index 81285e7..5afa814 100644
--- a/roseh.moe.go
+++ b/roseh.moe.go
@@ -18,7 +18,6 @@ import (
"log"
"net/http"
"os"
- "path/filepath"
"strings"
"sync"
"time"
@@ -28,10 +27,10 @@ import (
)
var (
- port = flag.Int("port", 42069, "port to listen on")
- selfURL = flag.String("self-url", "http://localhost:42069", "base URL of the server")
- secretsFile = flag.String("secrets", "secrets", "secrets file")
- redirectsDir = flag.String("redirect", "redirect", "directory containing Go package redirects")
+ port = flag.Int("port", 42069, "port to listen on")
+ selfURL = flag.String("self-url", "http://localhost:42069", "base URL of the server")
+ secretsFile = flag.String("secrets", "secrets", "secrets file")
+ configFile = flag.String("config", "config.ini", "configuration file (no spec or examples, sorry)")
serverStartTime = time.Now()
)
@@ -59,6 +58,82 @@ func loadSecrets() error {
return nil
}
+type serviceConfiguration struct {
+ packageRedirects map[string]string
+ commandRedirects map[string]string
+}
+
+var (
+ serviceConfigMu sync.Mutex
+ serviceConfig *serviceConfiguration
+ serviceConfigLastModified time.Time
+)
+
+func loadConfig() (*serviceConfiguration, error) {
+ stat, err := os.Stat(*configFile)
+ if err != nil {
+ return nil, err
+ }
+ serviceConfigMu.Lock()
+ oldConfig := serviceConfig
+ configLastModified := serviceConfigLastModified
+ serviceConfigMu.Unlock()
+ newModTime := stat.ModTime()
+ if !newModTime.After(configLastModified) {
+ return oldConfig, nil
+ }
+ f, err := os.Open(*configFile)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ config := &serviceConfiguration{
+ packageRedirects: make(map[string]string),
+ commandRedirects: make(map[string]string),
+ }
+ scanner := bufio.NewScanner(f)
+ lineNo := 0
+ var currentSection map[string]string
+ for scanner.Scan() {
+ lineNo++
+ line := strings.TrimSpace(scanner.Text())
+ if len(line) == 0 || strings.HasPrefix(line, "//") || strings.HasPrefix(line, "#") {
+ continue
+ }
+ if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
+ switch sectionName := strings.TrimSpace(line[1 : len(line)-1]); sectionName {
+ case "package-redirects":
+ currentSection = config.packageRedirects
+ case "command-redirects":
+ currentSection = config.commandRedirects
+ default:
+ currentSection = nil
+ log.Printf("Warning: %s:%d unknown section", *configFile, lineNo)
+ }
+ continue
+ }
+ key, val, ok := strings.Cut(line, "=")
+ if !ok {
+ log.Printf("Warning: %s:%d invalid key-value pair", *configFile, lineNo)
+ continue
+ }
+ if currentSection == nil {
+ log.Printf("Warning: %s:%d key-value pair outside section", *configFile, lineNo)
+ continue
+ }
+ key, val = strings.TrimSpace(key), strings.TrimSpace(val)
+ currentSection[key] = val
+ }
+ if err := scanner.Err(); err != nil {
+ return nil, err
+ }
+ serviceConfigMu.Lock()
+ serviceConfig = config
+ serviceConfigLastModified = newModTime
+ serviceConfigMu.Unlock()
+ return config, nil
+}
+
var (
//go:embed templates/404.html.template
notFoundString string
@@ -455,25 +530,13 @@ func autosave(w http.ResponseWriter, r *http.Request) {
}
}
-func findRedirect(kind, name string) (string, bool) {
- f, err := os.Open(filepath.Join(*redirectsDir, kind))
+func cmd(w http.ResponseWriter, r *http.Request) {
+ serviceConfig, err := loadConfig()
if err != nil {
- return "", false
- }
- defer f.Close()
- scanner := bufio.NewScanner(f)
- pfx := []byte(name + "\t")
- for scanner.Scan() {
- line := scanner.Bytes()
- if bytes.HasPrefix(line, pfx) {
- return string(line[len(pfx):]), true
- }
+ http.Error(w, fmt.Sprintf("load config: %s", err), http.StatusInternalServerError)
+ return
}
- return "", false
-}
-
-func cmd(w http.ResponseWriter, r *http.Request) {
- source, ok := findRedirect("cmd", r.PathValue("cmd"))
+ source, ok := serviceConfig.commandRedirects[r.PathValue("cmd")]
if !ok {
notFound(w, r)
return
@@ -486,7 +549,12 @@ func cmd(w http.ResponseWriter, r *http.Request) {
}
func pkg(w http.ResponseWriter, r *http.Request) {
- source, ok := findRedirect("pkg", r.PathValue("pkg"))
+ serviceConfig, err := loadConfig()
+ if err != nil {
+ http.Error(w, fmt.Sprintf("load config: %s", err), http.StatusInternalServerError)
+ return
+ }
+ source, ok := serviceConfig.packageRedirects[r.PathValue("pkg")]
if !ok {
notFound(w, r)
return