You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
2.6 KiB
Go
112 lines
2.6 KiB
Go
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
|
|
}
|