Using freegeoip.net we can get location information about hostnames or IP addresses. The service returns information like country name, latitude, and longitude. This example will use Go and its Unmarshal() function to decode the response in to a usable struct.
We make an HTTP GET request to freegeoip.net and it will return a JSON response. We read the HTTP JSON response in to a byte slice before we Unmarshal it to our GeoIP structure. The service supports JSON, XML, and CSV responses. It also supports input as hostnames, IPv4, and IPv6 addresses. In this example we call the /json/ URL to get the JSON response. We could just as easily modify our struct and the GET URL to use the XML format.
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type GeoIP struct {
// The right side is the name of the JSON variable
Ip string `json:"ip"`
CountryCode string `json:"country_code"`
CountryName string `json:"country_name""`
RegionCode string `json:"region_code"`
RegionName string `json:"region_name"`
City string `json:"city"`
Zipcode string `json:"zipcode"`
Lat float32 `json:"latitude"`
Lon float32 `json:"longitude"`
MetroCode int `json:"metro_code"`
AreaCode int `json:"area_code"`
}
var (
address string
err error
geo GeoIP
response *http.Response
body []byte
)
func main() {
// Provide a domain name or IP address
address = "www.devdungeon.com"
// address = "2600:3c00::f03c:91ff:fe98:c0f5"
// address = "45.79.8.237"
// Use freegeoip.net to get a JSON response
// There is also /xml/ and /csv/ formats available
response, err = http.Get("https://freegeoip.net/json/" + address)
if err != nil {
fmt.Println(err)
}
defer response.Body.Close()
// response.Body() is a reader type. We have
// to use ioutil.ReadAll() to read the data
// in to a byte slice(string)
body, err = ioutil.ReadAll(response.Body)
if err != nil {
fmt.Println(err)
}
// Unmarshal the JSON byte slice to a GeoIP struct
err = json.Unmarshal(body, &geo)
if err != nil {
fmt.Println(err)
}
// Everything accessible in struct now
fmt.Println("\n==== IP Geolocation Info ====\n")
fmt.Println("IP address:\t", geo.Ip)
fmt.Println("Country Code:\t", geo.CountryCode)
fmt.Println("Country Name:\t", geo.CountryName)
fmt.Println("Zip Code:\t", geo.Zipcode)
fmt.Println("Latitude:\t", geo.Lat)
fmt.Println("Longitude:\t", geo.Lon)
fmt.Println("Metro Code:\t", geo.MetroCode)
fmt.Println("Area Code:\t", geo.AreaCode)
}