Giter Site home page Giter Site logo

ip2location / ip2location-go Goto Github PK

View Code? Open in Web Editor NEW
432.0 9.0 90.0 78 KB

Use IP2Location geolocation database to lookup the geolocation information with IP2Location Go Package. It can be used to determine country, region, city, coordinates, zip code, time zone, ISP, domain name, connection type, area code, weather, MCC, MNC, mobile brand name, elevation, usage type, address type and IAB category that any IP address or hostname originates from.

Home Page: http://www.ip2location.com

License: MIT License

Go 100.00%
ip2location geolocation ip-geolocation ip-lookup ip-database geolocation-database ip-address

ip2location-go's People

Contributors

csucu avatar ip2location avatar themartorana avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ip2location-go's Issues

Re-write in idiomatic Go?

TL;DR: Could you have an actual Go programmer look over the library?

This library is not at all Go-ish.

Functions are not named idiomatically, and more importantly they should return any errors that occur, not print and ignore them. That is very poor form in Go. For example:

var (
	ErrInvalidAddress = errors.New("invalid IP address")
	ErrBadFile        = errors.New("invalid database file")
	ErrNotSupported   = errors.New("parameter not supported: database upgrade required")
)

// Open the ip2location .bin database. You must call Close() to close the database file.
Open(filename string) error  // not Open(dbpath string)

// All returns a record populated with all fields supported by the current database.
All(ip string) (Record, error)  // not Get_all(ipaddress string) IP2Locationrecord

Arguably, the Get_* functions should be combined in a single call that accepts a bitmask:

// Lookup returns a Record populated with the specified fields. ErrNotSupported is returned
// if any of the requested fields are not present in the current database.
Lookup(ip string, fields uint32) (Record, error)
// e.g.
r, err := ip2location.Lookup("127.0.0.1", ip2location.All)
r, err := ip2location.Lookup("127.0.0.1", ip2location.CountryShort|ip2location.Region|ip2location.City)

or one that accepts a variable number of field arguments:

// Lookup returns a Record populated with the specified fields. ErrNotSupported is returned
// if any of the requested fields are not present in the current database.
Lookup(ip string, fields ...uint32) (Record, error)
// e.g.
r, err := ip2location.Lookup("127.0.0.1")  // defaults to "All"
r, err := ip2location.Lookup("127.0.0.1", ip2location.CountryShort, ip2location.Region, ip2location.City)

This client doesn't support IP2Proxy database

I'm using the IP2Proxy database here: https://lite.ip2location.com/database/px2-ip-proxytype-country to parse the proxy type from the IP: 8.8.8.8. But the result is clearly wrong:

File read failed: EOF
country_short: DCH
country_long: �PUB�SES�TOR�VPN�WEB                                                    
region: This parameter is unavailable for selected data file. Please upgrade the data file.
city: This parameter is unavailable for selected data file. Please upgrade the data file.
isp: -
latitude: 0.000000
longitude: 0.000000
domain: This parameter is unavailable for selected data file. Please upgrade the data file.
zipcode: This parameter is unavailable for selected data file. Please upgrade the data file.
timezone: This parameter is unavailable for selected data file. Please upgrade the data file.
netspeed: This parameter is unavailable for selected data file. Please upgrade the data file.
iddcode: This parameter is unavailable for selected data file. Please upgrade the data file.
areacode: This parameter is unavailable for selected data file. Please upgrade the data file.
weatherstationcode: This parameter is unavailable for selected data file. Please upgrade the data file.
weatherstationname: This parameter is unavailable for selected data file. Please upgrade the data file.
mcc: This parameter is unavailable for selected data file. Please upgrade the data file.
mnc: This parameter is unavailable for selected data file. Please upgrade the data file.
mobilebrand: This parameter is unavailable for selected data file. Please upgrade the data file.
elevation: 0.000000
usagetype: This parameter is unavailable for selected data file. Please upgrade the data file.
api version: 8.0.3
--- PASS: TestIp2Location (0.00s)
PASS

Process finished with exit code 0

I guess this client only supports ip2location db instead of ip2proxy. Can you support ip2proxy? Thanks.

Idiomatic Go

Please make this package properly follow Go convention and operate like how a Go package should.

If you need assistance, I can do it within a day for a fee: Here are my other packages: https://github.com/rocketlaunchr

Currently, I can't even with confidence know when a ip address can/cant be converted.
I can't even Open and Close the database on a (http) per-request basis.

Timezone is empty and EOF is always an error

Hi, using the recent documentation and a recent lite version with timezone.
I am always getting an EOF error but the data is actually there so it is a minor issue, however, the Timezone is always empty.

Thanks.

Reduce GC pressure

Hi

I added benchmark to my local branch, found these GC performance issues

  1. in readuint32() method, binary.Read uses reflection and will allocate more memory then binary.LittleEndian.Uint32() , here are the benchmarks
# err = binary.Read(buf, binary.LittleEndian, &retval)
BenchmarkGetAll1-16        14084             84946 ns/op           10161 B/op        696 allocs/op

# using retval = binary.LittleEndian.Uint32(data[:])
BenchmarkGetAllOld-16              15841             75894 ns/op            5569 B/op        450 allocs/op
  1. math/big provides arbitrary precision, which allocates more memory, we could use a Uint128 library such as lukechampine.com/uint128 to store ipv4 and ipv6 as Uint128, here is the benchmark using Uint128
BenchmarkGetAllOld-16              17890             67029 ns/op            1776 B/op        276 allocs/op

Total performance improvement is 27%, and allocs/op decreases 60%.

Can I send a PR? If so I will need to add some tests, I only test it with ipv4 data.

My local commit

  1. binary.LittleEndian.Uint32
  2. Uint128

New library

I've written a new library for querying IP2Location and IP2Proxy databases, github.com/pg9182/ip2x. I'm currently refactoring the code generation and refining the library interface, but it's more or less feature-complete.

  • It supports Go 1.18+.
  • It supports querying using Go 1.18's new net/netip.Addr type, which is much more efficient than parsing the IP from a string every time.
  • It uses native integer types instead of big.Int, which is also much more efficient.
  • It's about 11x faster than this library when querying a single field, and 2x faster for all fields, while making a fraction of the number of allocations (2 for init, 1 for each lookup, plus 1 for each typed field get, or 2 for an untyped one).
  • It has comprehensive built-in documentation, including automatically-generated information about which fields are available in different product types.
  • It supports querying information about the database itself, for example, whether it supports IPv6, and which fields are available.
  • It has a more fluent and flexible API (e.g., record.Get(ip2x.Latitude), record.GetString(ip2x.Latitude), record.GetFloat(ip2x.Latitude))
  • It has built-in support for pretty-printing records as strings or JSON.
  • It supports both IP2Location databases in a single package with a unified API.
  • It uses code generation to simplify adding new products/types/fields/documentation while reducing the likelihood of bugs (input, docs).
  • It's written in idiomatic Go: correct error handling (rather than stuffing error strings into the record struct), useful zero values (an empty record will work properly), proper type names, etc.
  • There are tests to ensure the output is consistent with this library, that a range of IPv4 (and their possible IPv6-mappings) address work correctly, and other things. There are also fuzz tests to ensure IPs can't crash the library and are IPv4/v6-mapped correctly.

This library is already being used in production at Northstar for game server geolocation and log analysis.


$ cd test && go test -bench=. -benchmem .
db: IP2Location DB11 2022-10-29 [city,country_code,country_name,latitude,longitude,region,time_zone,zip_code] (IPv4+IPv6)
goos: linux
goarch: amd64
pkg: github.com/pg9182/ip2x/test
cpu: AMD Ryzen 5 5600G with Radeon Graphics         
BenchmarkIP2x_Init-12                       	17850333	        67.91 ns/op	     128 B/op	       2 allocs/op
BenchmarkIP2x_LookupOnly-12                 	18722506	        61.36 ns/op	      48 B/op	       1 allocs/op
BenchmarkIP2x_GetAll-12                     	 1522696	       812.2 ns/op	    1688 B/op	      14 allocs/op
BenchmarkIP2x_GetOneString-12               	 7839385	       144.1 ns/op	     304 B/op	       2 allocs/op
BenchmarkIP2x_GetOneFloat-12                	14312419	        84.16 ns/op	      48 B/op	       1 allocs/op
BenchmarkIP2x_GetTwoString-12               	 4243560	       244.9 ns/op	     560 B/op	       3 allocs/op
BenchmarkIP2x_GetTwoFloat-12                	12198259	       101.1 ns/op	      48 B/op	       1 allocs/op
BenchmarkIP2x_GetNonexistent-12             	14834245	        79.85 ns/op	      48 B/op	       1 allocs/op
BenchmarkIP2LocationV9_Init-12              	  602967	      2191 ns/op	     400 B/op	       7 allocs/op
BenchmarkIP2LocationV9_LookupOnly-12        	 1473849	       782.6 ns/op	     672 B/op	      24 allocs/op
BenchmarkIP2LocationV9_GetAll-12            	  819900	      1324 ns/op	    2268 B/op	      36 allocs/op
BenchmarkIP2LocationV9_GetOneString-12      	 1346534	       889.2 ns/op	     936 B/op	      26 allocs/op
BenchmarkIP2LocationV9_GetOneFloat-12       	 1441219	       795.0 ns/op	     672 B/op	      24 allocs/op
BenchmarkIP2LocationV9_GetTwoString-12      	  546868	      1866 ns/op	    1883 B/op	      53 allocs/op
BenchmarkIP2LocationV9_GetTwoFloat-12       	  693019	      1561 ns/op	    1345 B/op	      49 allocs/op
BenchmarkIP2LocationV9_GetNonexistent-12    	 1399872	       795.5 ns/op	     672 B/op	      24 allocs/op

Index out of range

I am encountering an issue when calling the OpenDB function.

Here is the output:

panic: runtime error: index out of range [80] with length 25

goroutine 33 [running]:
github.com/ip2location/ip2location-go.OpenDB({0xc0002d3f81, 0x9})
        /root/work/pkg/mod/github.com/ip2location/[email protected]+incompatible/ip2location.go:469 +0x74b
adv/adv/pkg/lib/geo.(*GeoRepository).AddGeoInfo(0xc00067cd00, {0xd4b0c0?, 0x1acb970?}, 0xc000392280)

And this is how I call it:

db, err := ip2location.OpenDB(g.db)
if err != nil {
	g.log.Fatal("geoReository: unable to open BIN database file", zap.String("db", g.db), zap.Error(err))
}
defer db.Close()

g.db is a path to the binary file given through config files

I am not sure what is causing this panic. Could anyone help me out?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.