diff --git a/cmd/echoip/main.go b/cmd/echoip/main.go index 8a83b40..0ad6e72 100644 --- a/cmd/echoip/main.go +++ b/cmd/echoip/main.go @@ -10,6 +10,9 @@ import ( "github.com/mpolden/echoip/http" "github.com/mpolden/echoip/iputil" "github.com/mpolden/echoip/iputil/geo" + parser "github.com/mpolden/echoip/iputil/paser" + "github.com/mpolden/echoip/iputil/stack" + "github.com/qioalice/ipstack" ) type multiValueFlag []string @@ -29,6 +32,9 @@ func init() { } func main() { + var ipstackApiKey string + database := flag.String("d", "geoip", "Which database to use, 'ipstack' or 'geoip'") + flag.StringVar(&ipstackApiKey, "S", "", "IP Stack API Key") countryFile := flag.String("f", "", "Path to GeoIP country database") cityFile := flag.String("c", "", "Path to GeoIP city database") asnFile := flag.String("a", "", "Path to GeoIP ASN database") @@ -42,19 +48,31 @@ func main() { var headers multiValueFlag flag.Var(&headers, "H", "Header to trust for remote IP, if present (e.g. X-Real-IP)") flag.Parse() + if len(flag.Args()) != 0 { flag.Usage() return } - // open GeoIP files - r, err := geo.Open(*countryFile, *cityFile, *asnFile) - if err != nil { - log.Fatal(err) - } - + var parser parser.Parser + if (*database == "geoip") { + geo, err := geo.Open(*countryFile, *cityFile, *asnFile) + if err != nil { + log.Fatal(err) + } + parser = &geo + } + + if (*database == "ipstack") { + if err := ipstack.Init(ipstackApiKey); err != nil { + log.Fatal(err) + } + ips := stack.IPstackParser{} + parser = &ips + } + cache := http.NewCache(*cacheSize) - server := http.New(&r, cache, *profile) + server := http.New(parser, cache, *profile) server.IPHeaders = headers if _, err := os.Stat(*template); err == nil { server.Template = *template diff --git a/http/cache.go b/http/cache.go index e77cf4c..2882fc9 100644 --- a/http/cache.go +++ b/http/cache.go @@ -7,7 +7,7 @@ import ( "net" "sync" - parser "github.com/mpolden/echoip/paser" + parser "github.com/mpolden/echoip/iputil/paser" ) type Cache struct { diff --git a/http/cache_test.go b/http/cache_test.go index 041adfd..c33aff9 100644 --- a/http/cache_test.go +++ b/http/cache_test.go @@ -5,7 +5,7 @@ import ( "net" "testing" - parser "github.com/mpolden/echoip/paser" + parser "github.com/mpolden/echoip/iputil/paser" ) func TestCacheCapacity(t *testing.T) { diff --git a/http/http.go b/http/http.go index 3723cea..017a37f 100644 --- a/http/http.go +++ b/http/http.go @@ -11,7 +11,7 @@ import ( "net/http/pprof" - parser "github.com/mpolden/echoip/paser" + parser "github.com/mpolden/echoip/iputil/paser" "github.com/mpolden/echoip/useragent" "net" diff --git a/http/http_test.go b/http/http_test.go index a3adad5..e1c5572 100644 --- a/http/http_test.go +++ b/http/http_test.go @@ -13,7 +13,7 @@ import ( "github.com/mpolden/echoip/iputil" "github.com/mpolden/echoip/iputil/geo" - parser "github.com/mpolden/echoip/paser" + parser "github.com/mpolden/echoip/iputil/paser" ) func lookupAddr(net.IP) (string, error) { return "localhost", nil } diff --git a/iputil/geo/geo.go b/iputil/geo/geo.go index ae0791d..f40ab30 100644 --- a/iputil/geo/geo.go +++ b/iputil/geo/geo.go @@ -6,7 +6,7 @@ import ( "net" "github.com/mpolden/echoip/iputil" - parser "github.com/mpolden/echoip/paser" + parser "github.com/mpolden/echoip/iputil/paser" geoip2 "github.com/oschwald/geoip2-golang" ) diff --git a/paser/parser.go b/iputil/paser/parser.go similarity index 100% rename from paser/parser.go rename to iputil/paser/parser.go diff --git a/iputil/stack/stack.go b/iputil/stack/stack.go new file mode 100644 index 0000000..ff8ee8b --- /dev/null +++ b/iputil/stack/stack.go @@ -0,0 +1,63 @@ +package stack + +import ( + "fmt" + "net" + + "github.com/mpolden/echoip/iputil" + parser "github.com/mpolden/echoip/iputil/paser" + "github.com/qioalice/ipstack" +) + +type IPstackParser struct { + response *ipstack.Response +} + +func (ips *IPstackParser) Parse(ip net.IP, hostname string) (parser.Response, error) { + res, err := ipstack.IP(ip.String()); + ips.response = res + if err != nil { + return parser.Response{}, err + } + fmt.Printf("%+v\n", res) + + + ipDecimal := iputil.ToDecimal(ip) + + + + parserResponse := parser.Response{ + Latitude: float64(res.Latitide), + Longitude: float64(res.Longitude), + Hostname: hostname, + IP: ip, + IPDecimal: ipDecimal, + Country: res.CountryName, + CountryISO: res.CountryCode, + RegionName: res.RegionName, + RegionCode: res.RegionCode, + MetroCode: 0, + PostalCode: res.Zip, + City: res.City, + } + + if res.Timezone != nil { + parserResponse.Timezone = res.Timezone.ID + } + + if res.Location != nil { + parserResponse.CountryEU = &res.Location.IsEU; + } + + if res.Connection != nil { + if res.Connection.ASN > 0 { + parserResponse.ASN = fmt.Sprintf("AS%d", res.Connection.ASN) + } + } + + return parserResponse, nil +} + +func (ips *IPstackParser) IsEmpty() bool { + return false +}