package main import ( "html/template" "net/http" "os" "github.com/GeertJohan/go.rice" "github.com/gorilla/pat" "github.com/pkg/errors" "github.com/urfave/cli" "github.com/urfave/negroni" ) const ( appName = "what-is-my-ip" appLabel = "[" + appName + "] " ) func main() { app := cli.NewApp() app.Name = appName app.Version = "0.4.0" app.Usage = "Webapp that gives the IP address for incoming requests" app.Action = action app.Flags = []cli.Flag{ cli.StringFlag{ Name: "address, a", Value: ":3000", EnvVar: "WHAT_IS_MY_IP_ADDRESS", Usage: "Address and port to bind to", }, cli.StringSliceFlag{ Name: "header, H", Value: &cli.StringSlice{"X-Real-IP", "X-Forwarded-For"}, Usage: "Headers to check in before checking the request itself", }, cli.StringFlag{ Name: "certificate, c", Value: "cert.pem", EnvVar: "WHAT_IS_MY_IP_CERTIFICATE", Usage: "path to certificate file for https server", }, cli.StringFlag{ Name: "key, k", Value: "key.pem", EnvVar: "WHAT_IS_MY_IP_KEY", Usage: "path to key file for https server", }, } app.Run(os.Args) } func action(c *cli.Context) error { address := c.String("address") certificate := c.String("certificate") key := c.String("key") handler, service, err := getHandler(c.StringSlice("header")) if err != nil { return err } service.logger.Printf("listening on %s\n", address) return http.ListenAndServeTLS(address, certificate, key, handler) } func getHandler(headers []string) (http.Handler, *Server, error) { logger := NewLogger() templateBox := rice.MustFindBox("templates") templateString, err := templateBox.String("index.tmpl") if err != nil { wrappedErr := errors.Wrap(err, "Could not read index.tmpl") logger.Println(wrappedErr) return nil, nil, wrappedErr } service := &Server{ headerNames: headers, logger: NewLogger(), tmpl: template.Must(template.New("index").Parse(templateString)), } recover := negroni.NewRecovery() recover.Logger = service.logger router := pat.New() router.Get("/html", service.handleHTTPAs(htmlResponse)) router.Get("/json", service.handleHTTPAs(jsonResponse)) router.Get("/text", service.handleHTTPAs(textResponse)) router.Get("/", func(resp http.ResponseWriter, req *http.Request) { if req.URL.Path == "/" { service.ServeHTTP(resp, req) } else { err := errors.New("path \"" + req.URL.Path + "\" not found") service.handleError(resp, http.StatusNotFound, err, "404 page not found\n") } }) n := negroni.New() n.Use(recover) n.Use(service.logger) n.UseHandler(router) return n, service, nil }