marmotte is a modern gopher server.
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.
 
 
marmotte/cmd/marmotte/main.go

135 lines
4.0 KiB

package main
import (
"beastieboy/marmotte/gopher"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
var Version string = "Unknown version"
func main() {
viper.SetEnvPrefix("marmotte")
viper.BindEnv("host")
viper.BindEnv("port")
viper.BindEnv("root")
viper.BindEnv("transport")
viper.BindEnv("logfile")
viper.BindEnv("users_gopherspace")
viper.BindEnv("errors")
viper.BindEnv("debug")
viper.BindEnv("configfile")
viper.SetDefault("host", "localhost")
viper.SetDefault("port", 7070)
viper.SetDefault("root", "/usr/local/marmotte")
viper.SetDefault("transport", "tcp")
viper.SetDefault("logfile", "/var/log/marmotte.log")
viper.SetDefault("users_gopherspace", "/users")
viper.SetDefault("errors", "/errors")
viper.SetDefault("debug", false)
viper.SetDefault("configfile", "/usr/local/etc/marmotte/marmotte.yaml")
pflag.String("host", "localhost", "the hostname the server sockets will bind to")
pflag.Int("port", 7070, "the port the server will listen on")
pflag.String("transport", "tcp", "the network transport protocol to use for sockets")
pflag.String("root", "/usr/local/marmotte", "the root directory where the documents can be found")
pflag.String("logfile", "/var/log/marmotte.log", "the logfile (not rotated)")
pflag.String("users_gopherspace", "/users", "the root directory for users gopherspace (~username)")
pflag.String("errors", "/errors", "the directory where the error templates can be found")
pflag.Bool("debug", false, "set logging level to Debug")
pflag.String("configfile", "/usr/local/etc/marmotte/marmotte.yaml", "YAML configuration file")
pflag.Parse()
viper.BindPFlags(pflag.CommandLine)
configfilename:= strings.TrimSuffix(filepath.Base(viper.GetString("configfile")),
filepath.Ext(viper.GetString("configfile")))
viper.SetConfigName(configfilename)
viper.SetConfigType("yaml")
configdir := filepath.Dir(viper.GetString("configfile"))
viper.AddConfigPath(configdir)
if err := viper.ReadInConfig(); err != nil {
fmt.Println(fmt.Errorf("wtf config file: %w", err))
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
fmt.Printf("Could not find configuration file %s / %s (%s); relying on command-line and defaults.\n", configfilename, configdir, viper.GetString("configfile"))
} else {
panic(fmt.Errorf("fatal error config file: %w", err))
}
}
debug := viper.GetBool("debug")
// Default level for this example is info, unless debug flag is present
zerolog.SetGlobalLevel(zerolog.InfoLevel)
if debug {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
}
f, err := os.OpenFile(viper.GetString("logfile"), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0660)
defer f.Close()
if err == nil {
log.Logger = log.Output(f)
} else {
log.Error().
Err(err).
Msg("Could not open log file")
}
log.Info().
Msg("Starting marmotte version " + Version)
log.Info().
Str("Root", viper.GetString("root")).
Send()
log.Info().
Str("Host", viper.GetString("host")).
Send()
log.Info().
Str("Port", viper.GetString("port")).
Send()
log.Info().
Str("Transport", viper.GetString("transport")).
Send()
log.Info().
Str("UsersGopherspace", viper.GetString("users_gopherspace")).
Send()
log.Info().
Str("ErrorRoot", viper.GetString("errors")).
Send()
ctx := &gopher.Context{ Root: viper.GetString("root"),
Host: viper.GetString("host"),
Port: viper.GetInt("port"),
TransportProtocol: viper.GetString("transport"),
UsersGopherspace: viper.GetString("users_gopherspace"),
ErrorRoot: viper.GetString("root") + "/" + viper.GetString("errors"),
}
ctx.DefaultRequestTransformers()
ctx.DefaultResponseTransformers()
// custom header for gophermaps
ctx.Headers = map[string][]string {
"all_gophermaps": { "Welcome to " + ctx.Host,
"This gopherhole is powered by marmotte"},
}
ctx.ResponseTransformers = append(ctx.ResponseTransformers, gopher.ResponseTransformer{
Transformer: gopher.HeaderTransformerFor("all_gophermaps"),
Predicate: gopher.GopherMapPredicate })
gopher.Serve(ctx)
}