-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathserver.go
131 lines (111 loc) · 3.41 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package main
import (
"fmt"
"net"
"net/http"
"runtime/debug"
"github.com/oschwald/geoip2-golang"
)
type GeoIPReader interface {
City(net.IP) (*geoip2.City, error)
ASN(net.IP) (*geoip2.ASN, error)
}
type Whois interface {
Query(string) (string, error)
}
type Middleware func(http.Handler) http.Handler
type server struct {
router *http.ServeMux
middleware []Middleware
dbASN GeoIPReader
dbCity GeoIPReader
whois Whois
}
func (s *server) AddMiddleware(middleware Middleware) {
s.middleware = append(s.middleware, middleware)
}
func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var handler http.Handler
handler = s.router
for _, m := range s.middleware {
handler = m(handler)
}
handler.ServeHTTP(w, r)
}
func (s *server) routes() {
buildRevision, buildTime := buildInfo()
s.router.HandleFunc("/", s.handleIndex())
s.router.HandleFunc("GET /about", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Location", "/help")
w.WriteHeader(http.StatusFound)
})
s.router.HandleFunc("GET /info", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Location", "/help")
w.WriteHeader(http.StatusFound)
})
s.router.HandleFunc("GET /version", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Location", "/help")
w.WriteHeader(http.StatusFound)
})
s.router.HandleFunc("GET /help", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
fmt.Fprintf(w, `ip.chuhlomin.com is a service for finding information about IP addresses.
It uses:
* GeoLite2 databases for ASN and GeoIP lookups,
* whois.iana.org for Whois queries.
Available endpoints:
/help - this page
/ - index page, redirects to /{ip}, where {ip} is your IP address
/{ip} - returns information about the IP address: ASN and GeoIP
/whois - redirects to /{ip}/whois if IP is known, otherwise returns 404
/{ip}/whois - returns the Whois information for the IP address
/{ip}/{mask} - displays the IP in binary format, visualizing the mask
Example usage:
curl -L https://ip.chuhlomin.com/
curl https://ip.chuhlomin.com/1.1.1.1
curl https://ip.chuhlomin.com/1.1.1.1/whois
curl https://ip.chuhlomin.com/192.168.0.0/24
Version: 1.0.0
Revision: %s
Build time: %s
Source code: https://github.com/chuhlomin/ip
Author: Constantine Chukhlomin
License: MIT
---
Known alternatives:
https://ip.me
https://ifconfig.co
https://httpbin.org/ip
https://ipinfo.io
https://whatismyipaddress.com
`,
buildRevision, buildTime)
})
s.router.HandleFunc("GET /robots.txt", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
fmt.Fprintf(w, "User-agent: *\nDisallow: /\n")
})
s.router.HandleFunc("GET /favicon.ico", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "./favicon.ico")
})
s.router.HandleFunc("GET /og.png", func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, "./og.png")
})
s.router.HandleFunc("GET /whois", s.handleWhois())
s.router.HandleFunc("GET /{ip}", s.handleIP())
s.router.HandleFunc("GET /{ip}/whois", s.handleIPWhois())
s.router.HandleFunc("GET /{ip}/{mask}", s.handleMask())
}
func buildInfo() (revision, time string) {
if info, ok := debug.ReadBuildInfo(); ok {
for _, setting := range info.Settings {
switch setting.Key {
case "vcs.revision":
revision = setting.Value
case "vcs.time":
time = setting.Value
}
}
}
return
}