package servlet import ( "encoding/json" "errors" "fmt" "geniuscartel.xyz/vinegar/vinegarUtil" "io/ioutil" ) type ( ConfigType string // ConfigEntry defines a single route configuration entry. // Used to configure routes from a JSON config file. ConfigEntry struct { // ConfigType indicates the type of route - Text, Image etc. ConfigType ConfigType // UrlPattern is the URL regex pattern to match for the route. UrlPattern string // FileLocation is the file path or directory to serve files from. FileLocation string // UseBuiltinCache indicates whether to use the built-in LRU cache. UseBuiltinCache bool } Config struct { ListeningAddress string Routes []ConfigEntry } ) const ( Text ConfigType = "Text" Image = "Image" SingleFile = "SingleFile" ) func CreateBlankConfig() *Config { conf := Config{ ListeningAddress: ":8080", Routes: make([]ConfigEntry, 0, 10), } dummyRoute := ConfigEntry{ ConfigType: Text, UrlPattern: "/*", FileLocation: "errors/", UseBuiltinCache: false, } conf.Routes = append(conf.Routes, dummyRoute) return &conf } func LoadConfig(pathlike string) (*VinegarHttpServlet, error) { contents, err := vinegarUtil.GetDiskContent(pathlike) if err != nil { CreateBlankConfig() return nil, err } conf := Config{} err = json.Unmarshal(*contents, &conf) if err != nil { return nil, err } servlet := NewServlet(conf.ListeningAddress) for _, v := range conf.Routes { constructor, err := getConstructorFunction(v.ConfigType) if err != nil { return nil, err } //we don't have to invoke servlet.AddRoute because the static routes already do that for us constructor(servlet, v.UrlPattern, v.FileLocation, v.UseBuiltinCache) } return servlet, nil } func (e ConfigEntry) toRoute(serv *VinegarHttpServlet) error { constructor, err := getConstructorFunction(e.ConfigType) if err != nil { return err } constructor(serv, e.UrlPattern, e.FileLocation, e.UseBuiltinCache) return nil } func getConstructorFunction(t ConfigType) (RouteConstructor, error) { switch t { case Text: return NewTextRoute, nil case Image: return NewImageRoute, nil case SingleFile: return NewSingleFileRoute, nil } return nil, errors.New(fmt.Sprintf("could not determine constructor for invalid ConfigType: %s", t)) } func GenerateBlankConfig() error { fileName := "servlet.json.template.tmpl" conf := CreateBlankConfig() content, err := json.Marshal(&conf) if err != nil { return err } fmt.Println("Generating a blank configuration file at ") ioutil.WriteFile(fileName, content, 0755) return nil }