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.
what-is-my-ip/what-is-my-ip.go

119 lines
2.6 KiB
Go

package main
import (
"errors"
"html/template"
"net/http"
"os"
"github.com/gorilla/pat"
"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 := getHandler(c.StringSlice("header"))
service.logger.Printf("listening on %s\n", address)
return http.ListenAndServeTLS(address, certificate, key, handler)
}
func getHandler(headers []string) (http.Handler, *Server) {
service := &Server{
headerNames: headers,
logger: NewLogger(),
tmpl: template.Must(template.New("html").Parse(htmlTemplate)),
}
recover := negroni.NewRecovery()
recover.Logger = service.logger
router := pat.New()
router.Get("/json", func(resp http.ResponseWriter, req *http.Request) {
service.handleHTTP(resp, req, jsonResponse)
})
router.Get("/text", func(resp http.ResponseWriter, req *http.Request) {
service.handleHTTP(resp, req, textResponse)
})
router.Get("/html", func(resp http.ResponseWriter, req *http.Request) {
service.handleHTTP(resp, req, htmlResponse)
})
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
}
const htmlTemplate = `<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>What is My IP?</title>
<style> .ip { text-align: center; } </style>
</head>
<body>
<div class="ip">{{.IP}}</div>
</body>
</html>`