mirror of
https://github.com/dcarrillo/whatismyip.git
synced 2025-07-01 22:09:26 +00:00
Make geo database usage optional (#39)
This commit is contained in:
@ -7,7 +7,6 @@ import (
|
||||
"strings"
|
||||
|
||||
validator "github.com/dcarrillo/whatismyip/internal/validator/uuid"
|
||||
"github.com/dcarrillo/whatismyip/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"github.com/patrickmn/go-cache"
|
||||
@ -16,10 +15,14 @@ import (
|
||||
type DNSJSONResponse struct {
|
||||
DNS dnsData `json:"dns"`
|
||||
}
|
||||
type dnsGeoData struct {
|
||||
Country string `json:"country,omitempty"`
|
||||
AsnOrganization string `json:"provider,omitempty"`
|
||||
}
|
||||
|
||||
type dnsData struct {
|
||||
IP string `json:"ip"`
|
||||
Country string `json:"country"`
|
||||
AsnOrganization string `json:"provider"`
|
||||
IP string `json:"ip"`
|
||||
dnsGeoData
|
||||
}
|
||||
|
||||
// TODO
|
||||
@ -67,12 +70,21 @@ func handleDNS(ctx *gin.Context, store *cache.Cache) {
|
||||
return
|
||||
}
|
||||
|
||||
geo := service.Geo{IP: ip}
|
||||
geoResp := dnsGeoData{}
|
||||
if geoSvc != nil {
|
||||
cityRecord := geoSvc.LookUpCity(ip)
|
||||
asnRecord := geoSvc.LookUpASN(ip)
|
||||
|
||||
geoResp = dnsGeoData{
|
||||
Country: cityRecord.Country.Names["en"],
|
||||
AsnOrganization: asnRecord.AutonomousSystemOrganization,
|
||||
}
|
||||
}
|
||||
|
||||
j := DNSJSONResponse{
|
||||
DNS: dnsData{
|
||||
IP: ipStr,
|
||||
Country: geo.LookUpCity().Country.Names["en"],
|
||||
AsnOrganization: geo.LookUpASN().AutonomousSystemOrganization,
|
||||
IP: ipStr,
|
||||
dnsGeoData: geoResp,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -7,25 +7,28 @@ import (
|
||||
|
||||
"github.com/dcarrillo/whatismyip/internal/httputils"
|
||||
"github.com/dcarrillo/whatismyip/internal/setting"
|
||||
"github.com/dcarrillo/whatismyip/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type GeoResponse struct {
|
||||
Country string `json:"country,omitempty"`
|
||||
CountryCode string `json:"country_code,omitempty"`
|
||||
City string `json:"city,omitempty"`
|
||||
Latitude float64 `json:"latitude,omitempty"`
|
||||
Longitude float64 `json:"longitude,omitempty"`
|
||||
PostalCode string `json:"postal_code,omitempty"`
|
||||
TimeZone string `json:"time_zone,omitempty"`
|
||||
ASN uint `json:"asn,omitempty"`
|
||||
ASNOrganization string `json:"asn_organization,omitempty"`
|
||||
}
|
||||
|
||||
type JSONResponse struct {
|
||||
IP string `json:"ip"`
|
||||
IPVersion byte `json:"ip_version"`
|
||||
ClientPort string `json:"client_port"`
|
||||
Country string `json:"country"`
|
||||
CountryCode string `json:"country_code"`
|
||||
City string `json:"city"`
|
||||
Latitude float64 `json:"latitude"`
|
||||
Longitude float64 `json:"longitude"`
|
||||
PostalCode string `json:"postal_code"`
|
||||
TimeZone string `json:"time_zone"`
|
||||
ASN uint `json:"asn"`
|
||||
ASNOrganization string `json:"asn_organization"`
|
||||
Host string `json:"host"`
|
||||
Headers http.Header `json:"headers"`
|
||||
IP string `json:"ip"`
|
||||
IPVersion byte `json:"ip_version"`
|
||||
ClientPort string `json:"client_port"`
|
||||
Host string `json:"host"`
|
||||
Headers http.Header `json:"headers"`
|
||||
GeoResponse
|
||||
}
|
||||
|
||||
func getRoot(ctx *gin.Context) {
|
||||
@ -66,16 +69,14 @@ func getClientPortAsString(ctx *gin.Context) {
|
||||
}
|
||||
|
||||
func getAllAsString(ctx *gin.Context) {
|
||||
output := "IP: " + ctx.ClientIP() + "\n"
|
||||
ip := net.ParseIP(ctx.ClientIP())
|
||||
|
||||
output := "IP: " + ip.String() + "\n"
|
||||
output += "Client Port: " + getClientPort(ctx) + "\n"
|
||||
|
||||
r := service.Geo{IP: net.ParseIP(ctx.ClientIP())}
|
||||
if record := r.LookUpCity(); record != nil {
|
||||
output += geoCityRecordToString(record) + "\n"
|
||||
}
|
||||
|
||||
if record := r.LookUpASN(); record != nil {
|
||||
output += geoASNRecordToString(record) + "\n"
|
||||
if geoSvc != nil {
|
||||
output += geoCityRecordToString(geoSvc.LookUpCity(ip)) + "\n"
|
||||
output += geoASNRecordToString(geoSvc.LookUpASN(ip)) + "\n"
|
||||
}
|
||||
|
||||
h := httputils.GetHeadersWithoutTrustedHeaders(ctx)
|
||||
@ -90,28 +91,37 @@ func getJSON(ctx *gin.Context) {
|
||||
}
|
||||
|
||||
func jsonOutput(ctx *gin.Context) JSONResponse {
|
||||
ip := service.Geo{IP: net.ParseIP(ctx.ClientIP())}
|
||||
asnRecord := ip.LookUpASN()
|
||||
cityRecord := ip.LookUpCity()
|
||||
ip := net.ParseIP(ctx.ClientIP())
|
||||
|
||||
var version byte = 4
|
||||
if p := net.ParseIP(ctx.ClientIP()).To4(); p == nil {
|
||||
if p := ip.To4(); p == nil {
|
||||
version = 6
|
||||
}
|
||||
|
||||
geoResp := GeoResponse{}
|
||||
if geoSvc != nil {
|
||||
cityRecord := geoSvc.LookUpCity(ip)
|
||||
asnRecord := geoSvc.LookUpASN(ip)
|
||||
|
||||
geoResp = GeoResponse{
|
||||
Country: cityRecord.Country.Names["en"],
|
||||
CountryCode: cityRecord.Country.ISOCode,
|
||||
City: cityRecord.City.Names["en"],
|
||||
Latitude: cityRecord.Location.Latitude,
|
||||
Longitude: cityRecord.Location.Longitude,
|
||||
PostalCode: cityRecord.Postal.Code,
|
||||
TimeZone: cityRecord.Location.TimeZone,
|
||||
ASN: asnRecord.AutonomousSystemNumber,
|
||||
ASNOrganization: asnRecord.AutonomousSystemOrganization,
|
||||
}
|
||||
}
|
||||
|
||||
return JSONResponse{
|
||||
IP: ctx.ClientIP(),
|
||||
IPVersion: version,
|
||||
ClientPort: getClientPort(ctx),
|
||||
Country: cityRecord.Country.Names["en"],
|
||||
CountryCode: cityRecord.Country.ISOCode,
|
||||
City: cityRecord.City.Names["en"],
|
||||
Latitude: cityRecord.Location.Latitude,
|
||||
Longitude: cityRecord.Location.Longitude,
|
||||
PostalCode: cityRecord.Postal.Code,
|
||||
TimeZone: cityRecord.Location.TimeZone,
|
||||
ASN: asnRecord.AutonomousSystemNumber,
|
||||
ASNOrganization: asnRecord.AutonomousSystemOrganization,
|
||||
Host: ctx.Request.Host,
|
||||
Headers: httputils.GetHeadersWithoutTrustedHeaders(ctx),
|
||||
IP: ip.String(),
|
||||
IPVersion: version,
|
||||
ClientPort: getClientPort(ctx),
|
||||
Host: ctx.Request.Host,
|
||||
Headers: httputils.GetHeadersWithoutTrustedHeaders(ctx),
|
||||
GeoResponse: geoResp,
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/dcarrillo/whatismyip/models"
|
||||
"github.com/dcarrillo/whatismyip/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@ -83,10 +82,13 @@ var asnOutput = map[string]asnDataFormatter{
|
||||
}
|
||||
|
||||
func getGeoAsString(ctx *gin.Context) {
|
||||
field := strings.ToLower(ctx.Params.ByName("field"))
|
||||
ip := service.Geo{IP: net.ParseIP(ctx.ClientIP())}
|
||||
record := ip.LookUpCity()
|
||||
if geoSvc == nil {
|
||||
ctx.String(http.StatusNotFound, http.StatusText(http.StatusNotFound))
|
||||
return
|
||||
}
|
||||
|
||||
field := strings.ToLower(ctx.Params.ByName("field"))
|
||||
record := geoSvc.LookUpCity(net.ParseIP(ctx.ClientIP()))
|
||||
if field == "" {
|
||||
ctx.String(http.StatusOK, geoCityRecordToString(record))
|
||||
} else if g, ok := geoOutput[field]; ok {
|
||||
@ -97,10 +99,12 @@ func getGeoAsString(ctx *gin.Context) {
|
||||
}
|
||||
|
||||
func getASNAsString(ctx *gin.Context) {
|
||||
if geoSvc == nil {
|
||||
ctx.String(http.StatusNotFound, http.StatusText(http.StatusNotFound))
|
||||
return
|
||||
}
|
||||
field := strings.ToLower(ctx.Params.ByName("field"))
|
||||
ip := service.Geo{IP: net.ParseIP(ctx.ClientIP())}
|
||||
record := ip.LookUpASN()
|
||||
|
||||
record := geoSvc.LookUpASN(net.ParseIP(ctx.ClientIP()))
|
||||
if field == "" {
|
||||
ctx.String(http.StatusOK, geoASNRecordToString(record))
|
||||
} else if g, ok := asnOutput[field]; ok {
|
||||
|
@ -5,9 +5,12 @@ import (
|
||||
"log"
|
||||
|
||||
"github.com/dcarrillo/whatismyip/internal/setting"
|
||||
"github.com/dcarrillo/whatismyip/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
var geoSvc *service.Geo
|
||||
|
||||
func SetupTemplate(r *gin.Engine) {
|
||||
if setting.App.TemplatePath == "" {
|
||||
t, _ := template.New("home").Parse(home)
|
||||
@ -18,7 +21,8 @@ func SetupTemplate(r *gin.Engine) {
|
||||
}
|
||||
}
|
||||
|
||||
func Setup(r *gin.Engine) {
|
||||
func Setup(r *gin.Engine, geo *service.Geo) {
|
||||
geoSvc = geo
|
||||
r.GET("/", getRoot)
|
||||
r.GET("/scan/tcp/:port", scanTCPPort)
|
||||
r.GET("/client-port", getClientPortAsString)
|
||||
|
@ -1,10 +1,11 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/dcarrillo/whatismyip/models"
|
||||
"github.com/dcarrillo/whatismyip/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@ -34,9 +35,9 @@ var (
|
||||
text: "text/plain; charset=utf-8",
|
||||
json: "application/json; charset=utf-8",
|
||||
}
|
||||
jsonIPv4 = `{"client_port":"1001","ip":"81.2.69.192","ip_version":4,"country":"United Kingdom","country_code":"GB","city":"London","latitude":51.5142,"longitude":-0.0931,"postal_code":"","time_zone":"Europe/London","asn":0,"asn_organization":"","host":"test", "headers": {}}`
|
||||
jsonIPv6 = `{"asn":3352, "asn_organization":"TELEFONICA DE ESPANA", "city":"", "client_port":"1001", "country":"", "country_code":"", "host":"test", "ip":"2a02:9000::1", "ip_version":6, "latitude":0, "longitude":0, "postal_code":"", "time_zone":"", "headers": {}}`
|
||||
jsonDNSIPv4 = `{"dns":{"ip":"81.2.69.192","country":"United Kingdom","provider":""}}`
|
||||
jsonIPv4 = `{"client_port":"1001","ip":"81.2.69.192","ip_version":4,"country":"United Kingdom","country_code":"GB","city":"London","latitude":51.5142,"longitude":-0.0931,"time_zone":"Europe/London","host":"test", "headers": {}}`
|
||||
jsonIPv6 = `{"asn":3352,"asn_organization":"TELEFONICA DE ESPANA","client_port":"1001","host":"test","ip":"2a02:9000::1","ip_version":6,"headers": {}}`
|
||||
jsonDNSIPv4 = `{"dns":{"ip":"81.2.69.192","country":"United Kingdom"}}`
|
||||
plainDNSIPv4 = "81.2.69.192 (United Kingdom / )\n"
|
||||
)
|
||||
|
||||
@ -49,9 +50,8 @@ const (
|
||||
func TestMain(m *testing.M) {
|
||||
app = gin.Default()
|
||||
app.TrustedPlatform = trustedHeader
|
||||
models.Setup("../test/GeoIP2-City-Test.mmdb", "../test/GeoLite2-ASN-Test.mmdb")
|
||||
Setup(app)
|
||||
defer models.CloseDBs()
|
||||
svc, _ := service.NewGeo(context.Background(), "../test/GeoIP2-City-Test.mmdb", "../test/GeoLite2-ASN-Test.mmdb")
|
||||
Setup(app, svc)
|
||||
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
@ -62,20 +62,22 @@ func TestDefaultTemplate(t *testing.T) {
|
||||
|
||||
tmpl, _ := template.New("home").Parse(home)
|
||||
response := JSONResponse{
|
||||
IP: "127.0.0.1",
|
||||
IPVersion: 4,
|
||||
ClientPort: "1000",
|
||||
Country: "A Country",
|
||||
CountryCode: "XX",
|
||||
City: "A City",
|
||||
Latitude: 100,
|
||||
Longitude: -100,
|
||||
PostalCode: "00000",
|
||||
TimeZone: "My/Timezone",
|
||||
ASN: 0,
|
||||
ASNOrganization: "My ISP",
|
||||
Host: "localhost",
|
||||
Headers: req.Header,
|
||||
IP: "127.0.0.1",
|
||||
IPVersion: 4,
|
||||
ClientPort: "1000",
|
||||
Host: "localhost",
|
||||
Headers: req.Header,
|
||||
GeoResponse: GeoResponse{
|
||||
Country: "A Country",
|
||||
CountryCode: "XX",
|
||||
City: "A City",
|
||||
Latitude: 100,
|
||||
Longitude: -100,
|
||||
PostalCode: "00000",
|
||||
TimeZone: "My/Timezone",
|
||||
ASN: 0,
|
||||
ASNOrganization: "My ISP",
|
||||
},
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
|
Reference in New Issue
Block a user