You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
2.1 KiB
110 lines
2.1 KiB
package main |
|
|
|
import ( |
|
"errors" |
|
"io/ioutil" |
|
"log" |
|
"os" |
|
"regexp" |
|
"strconv" |
|
"strings" |
|
|
|
"github.com/kballard/go-shellquote" |
|
"gopkg.in/yaml.v3" |
|
) |
|
|
|
type pathConfig struct { |
|
// Path to match |
|
Path string |
|
|
|
// Resource to serve |
|
Root string |
|
Proxy string |
|
Command string |
|
|
|
// List directory entries |
|
ListDirectory bool |
|
|
|
r *regexp.Regexp |
|
cmd []string |
|
} |
|
|
|
type certConfig struct { |
|
Cert string |
|
Key string |
|
} |
|
|
|
type serverConfig struct { |
|
Listen string |
|
|
|
Certificates []*certConfig |
|
|
|
Hosts map[string][]*pathConfig |
|
|
|
hostname string |
|
port int |
|
} |
|
|
|
var config = &serverConfig{ |
|
hostname: "localhost", |
|
port: 1965, |
|
} |
|
|
|
func readconfig(configPath string) error { |
|
if configPath == "" { |
|
return errors.New("file unspecified") |
|
} |
|
|
|
if _, err := os.Stat(configPath); os.IsNotExist(err) { |
|
return errors.New("file not found") |
|
} |
|
|
|
configData, err := ioutil.ReadFile(configPath) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
err = yaml.Unmarshal(configData, &config) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
split := strings.Split(config.Listen, ":") |
|
if len(split) != 2 { |
|
config.hostname = config.Listen |
|
config.Listen += ":1965" |
|
} else { |
|
config.hostname = split[0] |
|
config.port, err = strconv.Atoi(split[1]) |
|
if err != nil { |
|
log.Fatalf("invalid port specified: %s", err) |
|
} |
|
} |
|
|
|
for _, paths := range config.Hosts { |
|
for _, serve := range paths { |
|
if serve.Path == "" { |
|
log.Fatal("path must be specified in serve entry") |
|
} else if (serve.Root != "" && (serve.Proxy != "" || serve.Command != "")) || |
|
(serve.Proxy != "" && (serve.Root != "" || serve.Command != "")) || |
|
(serve.Command != "" && (serve.Root != "" || serve.Proxy != "")) { |
|
log.Fatal("only one root, reverse proxy or command may specified in a serve entry") |
|
} |
|
|
|
if serve.Path[0] == '^' { |
|
serve.r = regexp.MustCompile(serve.Path) |
|
} else if serve.Path[len(serve.Path)-1] == '/' { |
|
serve.Path = serve.Path[:len(serve.Path)-1] |
|
} |
|
|
|
if serve.Command != "" { |
|
serve.cmd, err = shellquote.Split(serve.Command) |
|
if err != nil { |
|
log.Fatalf("failed to parse command %s: %s", serve.cmd, err) |
|
} |
|
} |
|
} |
|
} |
|
|
|
return nil |
|
}
|
|
|