mirror of https://github.com/mpolden/echoip
parent
cfb86fe124
commit
6a9202851d
|
@ -40,7 +40,8 @@ $ http --json ifconfig.co
|
||||||
{
|
{
|
||||||
"city": "Bornyasherk",
|
"city": "Bornyasherk",
|
||||||
"country": "Elbonia",
|
"country": "Elbonia",
|
||||||
"ip": "127.0.0.1"
|
"ip": "127.0.0.1",
|
||||||
|
"ip_decimal": 2130706433
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
30
api/api.go
30
api/api.go
|
@ -6,6 +6,7 @@ import (
|
||||||
"html/template"
|
"html/template"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
|
"math/big"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -29,10 +30,11 @@ type API struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Response struct {
|
type Response struct {
|
||||||
IP net.IP `json:"ip"`
|
IP net.IP `json:"ip"`
|
||||||
Country string `json:"country,omitempty"`
|
IPDecimal *big.Int `json:"ip_decimal"`
|
||||||
City string `json:"city,omitempty"`
|
Country string `json:"country,omitempty"`
|
||||||
Hostname string `json:"hostname,omitempty"`
|
City string `json:"city,omitempty"`
|
||||||
|
Hostname string `json:"hostname,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PortResponse struct {
|
type PortResponse struct {
|
||||||
|
@ -45,6 +47,16 @@ func New(oracle Oracle) *API {
|
||||||
return &API{oracle: oracle}
|
return &API{oracle: oracle}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ipToDecimal(ip net.IP) *big.Int {
|
||||||
|
i := big.NewInt(0)
|
||||||
|
if to4 := ip.To4(); to4 != nil {
|
||||||
|
i.SetBytes(to4)
|
||||||
|
} else {
|
||||||
|
i.SetBytes(ip)
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
func ipFromRequest(header string, r *http.Request) (net.IP, error) {
|
func ipFromRequest(header string, r *http.Request) (net.IP, error) {
|
||||||
remoteIP := r.Header.Get(header)
|
remoteIP := r.Header.Get(header)
|
||||||
if remoteIP == "" {
|
if remoteIP == "" {
|
||||||
|
@ -66,6 +78,7 @@ func (a *API) newResponse(r *http.Request) (Response, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Response{}, err
|
return Response{}, err
|
||||||
}
|
}
|
||||||
|
ipDecimal := ipToDecimal(ip)
|
||||||
country, err := a.oracle.LookupCountry(ip)
|
country, err := a.oracle.LookupCountry(ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
|
@ -79,10 +92,11 @@ func (a *API) newResponse(r *http.Request) (Response, error) {
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
}
|
}
|
||||||
return Response{
|
return Response{
|
||||||
IP: ip,
|
IP: ip,
|
||||||
Country: country,
|
IPDecimal: ipDecimal,
|
||||||
City: city,
|
Country: country,
|
||||||
Hostname: strings.Join(hostnames, " "),
|
City: city,
|
||||||
|
Hostname: strings.Join(hostnames, " "),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package api
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
|
"math/big"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
@ -84,7 +85,7 @@ func TestJSONHandlers(t *testing.T) {
|
||||||
out string
|
out string
|
||||||
status int
|
status int
|
||||||
}{
|
}{
|
||||||
{s.URL, `{"ip":"127.0.0.1","country":"Elbonia","city":"Bornyasherk","hostname":"localhost"}`, 200},
|
{s.URL, `{"ip":"127.0.0.1","ip_decimal":2130706433,"country":"Elbonia","city":"Bornyasherk","hostname":"localhost"}`, 200},
|
||||||
{s.URL + "/port/foo", `{"error":"404 page not found"}`, 404},
|
{s.URL + "/port/foo", `{"error":"404 page not found"}`, 404},
|
||||||
{s.URL + "/port/0", `{"error":"Invalid port: 0"}`, 400},
|
{s.URL + "/port/0", `{"error":"Invalid port: 0"}`, 400},
|
||||||
{s.URL + "/port/65356", `{"error":"Invalid port: 65356"}`, 400},
|
{s.URL + "/port/65356", `{"error":"Invalid port: 65356"}`, 400},
|
||||||
|
@ -161,3 +162,19 @@ func TestCLIMatcher(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIPToDecimal(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
in string
|
||||||
|
out *big.Int
|
||||||
|
}{
|
||||||
|
{"127.0.0.1", big.NewInt(2130706433)},
|
||||||
|
{"::1", big.NewInt(1)},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
i := ipToDecimal(net.ParseIP(tt.in))
|
||||||
|
if i.Cmp(tt.out) != 0 {
|
||||||
|
t.Errorf("Expected %d, got %d for IP %s", tt.out, i, tt.in)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -80,7 +80,8 @@ $ http ifconfig.co/json
|
||||||
"city": "{{ .City }}",{{ end }}{{ if .IsLookupCountryEnabled }}
|
"city": "{{ .City }}",{{ end }}{{ if .IsLookupCountryEnabled }}
|
||||||
"country": "{{ .Country }}",{{ end }}{{ if .IsLookupAddrEnabled }}
|
"country": "{{ .Country }}",{{ end }}{{ if .IsLookupAddrEnabled }}
|
||||||
"hostname": "{{ .Hostname }}",{{ end }}
|
"hostname": "{{ .Hostname }}",{{ end }}
|
||||||
"ip": "{{ .IP }}"
|
"ip": "{{ .IP }}",
|
||||||
|
"ip_decimal": {{ .IPDecimal }}
|
||||||
}
|
}
|
||||||
|
|
||||||
# or set Accept header:
|
# or set Accept header:
|
||||||
|
|
Loading…
Reference in New Issue