Add support for /<header-name>

This commit is contained in:
Martin Polden 2012-11-25 13:30:39 +01:00
parent f1d987d8f9
commit 17551cbf6d
2 changed files with 89 additions and 25 deletions

View File

@ -8,10 +8,13 @@ import (
"net"
"net/http"
"regexp"
"strings"
)
type Client struct {
IP net.IP
Port string
Header http.Header
}
func isCli(userAgent string) bool {
@ -20,32 +23,55 @@ func isCli(userAgent string) bool {
return match
}
func parseRealIP(req *http.Request) (net.IP, string) {
var host string
var port string
realIP := req.Header.Get("X-Real-IP")
if realIP != "" {
host = realIP
} else {
host, port, _ = net.SplitHostPort(req.RemoteAddr)
}
return net.ParseIP(host), port
}
func pathToKey(path string) string {
re := regexp.MustCompile("^\\/|\\.json$")
return re.ReplaceAllLiteralString(strings.ToLower(path), "")
}
func isJson(req *http.Request) bool {
return strings.HasSuffix(req.URL.Path, ".json") ||
strings.Contains(req.Header.Get("Accept"), "application/json")
}
func handler(w http.ResponseWriter, req *http.Request) {
if req.Method != "GET" {
http.Error(w, "Invalid request method", 405)
return
}
var host string
var err error
realIP := req.Header.Get("X-Real-IP")
if realIP != "" {
host = realIP
} else {
host, _, err = net.SplitHostPort(req.RemoteAddr)
}
ip := net.ParseIP(host)
if err != nil {
log.Printf("Failed to parse remote address: %s\n", req.RemoteAddr)
http.Error(w, "Failed to parse remote address", 500)
return
}
ip, port := parseRealIP(req)
header := pathToKey(req.URL.Path)
if isCli(req.UserAgent()) {
io.WriteString(w, fmt.Sprintf("%s\n", ip))
if header == "" || header == "ip" {
io.WriteString(w, fmt.Sprintf("%s\n", ip))
} else if header == "port" {
io.WriteString(w, fmt.Sprintf("%s\n", port))
} else {
value := req.Header.Get(header)
io.WriteString(w, fmt.Sprintf("%s\n", value))
}
} else {
t, _ := template.ParseFiles("index.html")
client := &Client{IP: ip}
funcMap := template.FuncMap {
"ToLower": strings.ToLower,
}
t, _ := template.
New("index.html").
Funcs(funcMap).
ParseFiles("index.html")
client := &Client{IP: ip, Port: port, Header: req.Header}
t.Execute(w, client)
}
}

View File

@ -5,13 +5,16 @@
<title>What is my IP address &mdash; ifconfig.co</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Lookup my IP address">
<link href='http://fonts.googleapis.com/css?family=Oswald' rel='stylesheet' type='text/css'>
<link href="http://fonts.googleapis.com/css?family=Oswald" rel="stylesheet" type="text/css">
<link href="/assets/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<style>
h1, p {
font-family: 'Oswald', sans-serif;
body {
padding-top: 60px;
font-family: "Oswald", sans-serif;
}
.ip {
font-size: 1.5em;
.response {
font-family: "Monaco", "Menlo", "Consolas", "Courier New", monospace;
font-size: 12px;
}
#wrapper {
margin: 0 auto;
@ -20,9 +23,44 @@
</style>
</head>
<body>
<div id="wrapper">
<h1>What is my IP address?</h1>
<p>Your IP address is: <br><span class="ip">{{ .IP }}</span></p>
<div class="container">
<div class="row">
<div id="wrapper">
<h1>What is my IP address?</h1>
<p>Your IP address is:</p>
<h2>{{ .IP }}</h2>
</div>
</div>
<div class="row">
<div class="span12">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th class="span4">Command</th>
<th>Response</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>curl ifconfig.co</code></td>
<td class="response">{{ .IP }}</td>
</tr>
<tr>
<td><code>curl ifconfig.co/port</code></td>
<td class="response">{{ .Port }}</td>
</tr>
{{ if $self := . }}
{{ range $key, $value := .Header }}
<tr>
<td><code>curl ifconfig.co/{{ ToLower $key }}</code></td>
<td class="response">{{ index $self.Header $key }}
</tr>
{{end}}
{{end}}
</tbody>
</table>
</div>
</div>
</div>
<a href="https://github.com/martinp/ifconfig"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a>
</body>