package main import ( "fmt" "html/template" "image/png" "io/ioutil" "log" "net" "net/http" "net/url" "path/filepath" "strings" "git.sr.ht/~mendelmaleh/dummy" "git.sr.ht/~mendelmaleh/freetype" "git.sr.ht/~mendelmaleh/freetype/truetype" "github.com/pelletier/go-toml" "golang.org/x/net/netutil" ) type Config struct { Dummy struct { Conns int Addr, Pattern, Fonts, Font string } } var fonts = make(map[string]*truetype.Font) func main() { doc, err := ioutil.ReadFile("config.toml") if err != nil { log.Fatal(err) } config := Config{} err = toml.Unmarshal(doc, &config) if err != nil { log.Fatal(err) } fontfiles, err := ioutil.ReadDir(config.Dummy.Fonts) if err != nil { log.Fatal(err) } for _, file := range fontfiles { if filepath.Ext(file.Name()) != ".ttf" { continue } filebytes, err := ioutil.ReadFile(config.Dummy.Fonts + file.Name()) if err != nil { log.Println(err) // don't exit if one font doesn't work continue } font, err := freetype.ParseFont(filebytes) if err != nil { log.Println(err) continue } // fmt.Println(font.Name(truetype.NameIDFontFamily)) fonts[font.Name(truetype.NameIDFontFamily)] = font } if len(fonts) < 1 { log.Fatal("No fonts loaded") } // set default font after it's loaded font, ok := fonts[config.Dummy.Font] if !ok { log.Fatal("Default font not found") } dopt := dummy.DefaultOptions dopt.Font = font tmpl := template.New("web").Funcs(template.FuncMap{"title": strings.Title}) tmpl = template.Must(tmpl.Parse(` {{ title .Name }} `)) http.HandleFunc(config.Dummy.Pattern, func(w http.ResponseWriter, r *http.Request) { Dummy(w, r, Options{dopt.Copy()}) }, ) http.HandleFunc(config.Dummy.Pattern+"web/", func(w http.ResponseWriter, r *http.Request) { Web(w, r, Options{dopt.Copy()}, config, tmpl) }, ) listener, err := net.Listen("tcp", config.Dummy.Addr) if err != nil { log.Fatal(err) } listener = netutil.LimitListener(listener, config.Dummy.Conns) log.Panic(http.Serve(listener, nil)) } func Dummy(w http.ResponseWriter, r *http.Request, opt Options) { err := r.ParseForm() if err != nil { fmt.Fprintln(w, err) return } err = opt.FromForm(r.Form) if err != nil { fmt.Fprintln(w, err) return } im := dummy.Image(opt.Options) png.Encode(w, im) // fmt.Fprintf(w, "%+v\n", dopt) } func Web(w http.ResponseWriter, r *http.Request, opt Options, config Config, tmpl *template.Template) { err := r.ParseForm() if err != nil { fmt.Fprintln(w, err) return } err = opt.FromForm(r.Form) if err != nil { fmt.Fprintln(w, err) return } u := url.URL{ Host: r.Host, RawQuery: r.URL.RawQuery, Path: config.Dummy.Pattern, } if v, ok := r.Header["X-Forwarded-Proto"]; ok { u.Scheme = strings.Join(v, "") } else { u.Scheme = "http" } tmpl.Execute(w, struct { Name, Desc string Image template.URL }{"Dummy", opt.Desc, template.URL(u.String())}) }