mirror of https://github.com/mpolden/echoip
Merge pull request #3 from levelsoftware/adding-extra-ipstack-fields
Adding More IP Stack Fields
This commit is contained in:
commit
9971835402
|
@ -1,30 +0,0 @@
|
||||||
name: ci
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [master]
|
|
||||||
pull_request:
|
|
||||||
branches: [master]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: install go
|
|
||||||
uses: actions/setup-go@v2
|
|
||||||
with:
|
|
||||||
go-version: 1.16
|
|
||||||
- name: build and test
|
|
||||||
run: make
|
|
||||||
- name: enable experimental docker features
|
|
||||||
if: ${{ github.ref == 'refs/heads/master' }}
|
|
||||||
run: |
|
|
||||||
echo '{"experimental":true}' | sudo tee /etc/docker/daemon.json
|
|
||||||
sudo service docker restart
|
|
||||||
- name: publish multi-arch docker image
|
|
||||||
if: ${{ github.ref == 'refs/heads/master' }}
|
|
||||||
run: make docker-pushx
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
name: Go
|
||||||
|
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Go
|
||||||
|
uses: actions/setup-go@v4
|
||||||
|
with:
|
||||||
|
go-version: "1.13.x"
|
||||||
|
|
||||||
|
- name: Display Go version
|
||||||
|
run: go version
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: go test ./...
|
|
@ -2,4 +2,5 @@
|
||||||
/custom.html
|
/custom.html
|
||||||
/vendor/
|
/vendor/
|
||||||
.vscode/
|
.vscode/
|
||||||
|
.idea/
|
||||||
/bin/
|
/bin/
|
||||||
|
|
|
@ -7,11 +7,11 @@ import (
|
||||||
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/mpolden/echoip/http"
|
"github.com/levelsoftware/echoip/http"
|
||||||
"github.com/mpolden/echoip/iputil"
|
"github.com/levelsoftware/echoip/iputil"
|
||||||
"github.com/mpolden/echoip/iputil/geo"
|
"github.com/levelsoftware/echoip/iputil/geo"
|
||||||
"github.com/mpolden/echoip/iputil/ipstack"
|
"github.com/levelsoftware/echoip/iputil/ipstack"
|
||||||
parser "github.com/mpolden/echoip/iputil/paser"
|
parser "github.com/levelsoftware/echoip/iputil/paser"
|
||||||
ipstackApi "github.com/qioalice/ipstack"
|
ipstackApi "github.com/qioalice/ipstack"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -1,9 +1,9 @@
|
||||||
module github.com/mpolden/echoip
|
module github.com/levelsoftware/echoip
|
||||||
|
|
||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/oschwald/geoip2-golang v1.5.0
|
github.com/oschwald/geoip2-golang v1.5.0
|
||||||
github.com/qioalice/ipstack v1.0.1 // indirect
|
github.com/qioalice/ipstack v1.0.1
|
||||||
golang.org/x/sys v0.0.0-20210223212115-eede4237b368 // indirect
|
golang.org/x/sys v0.0.0-20210223212115-eede4237b368 // indirect
|
||||||
)
|
)
|
||||||
|
|
1
go.sum
1
go.sum
|
@ -12,7 +12,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76 h1:Dho5nD6R3PcW2SH1or8vS0dszDaXRxIw55lBX7XiE5g=
|
|
||||||
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210223212115-eede4237b368 h1:fDE3p0qf2V1co1vfj3/o87Ps8Hq6QTGNxJ5Xe7xSp80=
|
golang.org/x/sys v0.0.0-20210223212115-eede4237b368 h1:fDE3p0qf2V1co1vfj3/o87Ps8Hq6QTGNxJ5Xe7xSp80=
|
||||||
golang.org/x/sys v0.0.0-20210223212115-eede4237b368/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210223212115-eede4237b368/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
|
|
@ -113,10 +113,9 @@
|
||||||
<th scope="row">Timezone</th>
|
<th scope="row">Timezone</th>
|
||||||
<td>{{ .Timezone }}</td>
|
<td>{{ .Timezone }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{ end }} {{ if .IsDayLightSavings }}
|
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Is Daylight Savings?</th>
|
<th scope="row">Is Daylight Savings?</th>
|
||||||
<td>{{ .IsDayLightSavings }}</td>
|
<td>{{ .TimezoneEtc.IsDaylightSavings }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{ end }} {{ if .ASN }}
|
{{ end }} {{ if .ASN }}
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -153,35 +152,35 @@
|
||||||
{{ if .IPStackSecurityEnabled }}
|
{{ if .IPStackSecurityEnabled }}
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Is Proxy?</th>
|
<th scope="row">Is Proxy?</th>
|
||||||
<td>{{ .IsProxy }}</td>
|
<td>{{ .Security.IsProxy }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Is Crawler?</th>
|
<th scope="row">Is Crawler?</th>
|
||||||
<td>{{ .IsCrawler }}</td>
|
<td>{{ .Security.IsCrawler }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
{{ if .IsCrawler }}
|
{{ if .Security.IsCrawler }}
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Crawler Name</th>
|
<th scope="row">Crawler Name</th>
|
||||||
<td>{{ .CrawlerName }}</td>
|
<td>{{ .Security.CrawlerName }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Crawler Type</th>
|
<th scope="row">Crawler Type</th>
|
||||||
<td>{{ .CrawlerType }}</td>
|
<td>{{ .Security.CrawlerType }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Is Tor?</th>
|
<th scope="row">Is Tor?</th>
|
||||||
<td>{{ .IsTor }}</td>
|
<td>{{ .Security.IsTor }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Threat Level</th>
|
<th scope="row">Threat Level</th>
|
||||||
<td>{{ .ThreatLevel }}</td>
|
<td>{{ .Security.ThreatLevel }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Threat Types</th>
|
<th scope="row">Threat Types</th>
|
||||||
<td>{{ .ThreatTypes }}</td>
|
<td>{{ .Security.ThreatTypes }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
parser "github.com/mpolden/echoip/iputil/paser"
|
parser "github.com/levelsoftware/echoip/iputil/paser"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Cache struct {
|
type Cache struct {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
parser "github.com/mpolden/echoip/iputil/paser"
|
parser "github.com/levelsoftware/echoip/iputil/paser"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCacheCapacity(t *testing.T) {
|
func TestCacheCapacity(t *testing.T) {
|
||||||
|
|
|
@ -11,8 +11,8 @@ import (
|
||||||
|
|
||||||
"net/http/pprof"
|
"net/http/pprof"
|
||||||
|
|
||||||
parser "github.com/mpolden/echoip/iputil/paser"
|
parser "github.com/levelsoftware/echoip/iputil/paser"
|
||||||
"github.com/mpolden/echoip/useragent"
|
"github.com/levelsoftware/echoip/useragent"
|
||||||
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
|
@ -11,9 +11,9 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/mpolden/echoip/iputil"
|
"github.com/levelsoftware/echoip/iputil"
|
||||||
"github.com/mpolden/echoip/iputil/geo"
|
"github.com/levelsoftware/echoip/iputil/geo"
|
||||||
parser "github.com/mpolden/echoip/iputil/paser"
|
parser "github.com/levelsoftware/echoip/iputil/paser"
|
||||||
)
|
)
|
||||||
|
|
||||||
func lookupAddr(net.IP) (string, error) { return "localhost", nil }
|
func lookupAddr(net.IP) (string, error) { return "localhost", nil }
|
||||||
|
@ -163,7 +163,7 @@ func TestDisabledHandlers(t *testing.T) {
|
||||||
{s.URL + "/country", "404 page not found", 404},
|
{s.URL + "/country", "404 page not found", 404},
|
||||||
{s.URL + "/country-iso", "404 page not found", 404},
|
{s.URL + "/country-iso", "404 page not found", 404},
|
||||||
{s.URL + "/city", "404 page not found", 404},
|
{s.URL + "/city", "404 page not found", 404},
|
||||||
{s.URL + "/json", "{\n \"UsingGeoIP\": true,\n \"UsingIPStack\": false,\n \"IPStackSecurityEnabled\": false,\n \"ip\": \"127.0.0.1\",\n \"ip_decimal\": 2130706433\n}", 200},
|
{s.URL + "/json", "{\n \"UsingGeoIP\": true,\n \"UsingIPStack\": false,\n \"IPStackSecurityEnabled\": false,\n \"timezone_etc\": {},\n \"security\": {\n \"is_proxy\": false,\n \"is_crawler\": false,\n \"is_tor\": false\n },\n \"currency\": {},\n \"location\": {\n \"country_flag\": {}\n },\n \"ip\": \"127.0.0.1\",\n \"ip_decimal\": 2130706433\n}", 200},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
|
@ -189,7 +189,7 @@ func TestJSONHandlers(t *testing.T) {
|
||||||
out string
|
out string
|
||||||
status int
|
status int
|
||||||
}{
|
}{
|
||||||
{s.URL, "{\n \"UsingGeoIP\": true,\n \"UsingIPStack\": false,\n \"IPStackSecurityEnabled\": false,\n \"ip\": \"127.0.0.1\",\n \"ip_decimal\": 2130706433,\n \"country\": \"Elbonia\",\n \"country_iso\": \"EB\",\n \"country_eu\": false,\n \"region_name\": \"North Elbonia\",\n \"region_code\": \"1234\",\n \"metro_code\": 1234,\n \"zip_code\": \"1234\",\n \"city\": \"Bornyasherk\",\n \"latitude\": 63.416667,\n \"longitude\": 10.416667,\n \"time_zone\": \"Europe/Bornyasherk\",\n \"asn\": \"AS59795\",\n \"asn_org\": \"Hosting4Real\",\n \"hostname\": \"localhost\",\n \"user_agent\": {\n \"product\": \"curl\",\n \"version\": \"7.2.6.0\",\n \"raw_value\": \"curl/7.2.6.0\"\n }\n}", 200},
|
{s.URL, "{\n \"UsingGeoIP\": true,\n \"UsingIPStack\": false,\n \"IPStackSecurityEnabled\": false,\n \"timezone_etc\": {},\n \"security\": {\n \"is_proxy\": false,\n \"is_crawler\": false,\n \"is_tor\": false\n },\n \"currency\": {},\n \"location\": {\n \"country_flag\": {}\n },\n \"ip\": \"127.0.0.1\",\n \"ip_decimal\": 2130706433,\n \"country\": \"Elbonia\",\n \"country_iso\": \"EB\",\n \"country_eu\": false,\n \"region_name\": \"North Elbonia\",\n \"region_code\": \"1234\",\n \"metro_code\": 1234,\n \"zip_code\": \"1234\",\n \"city\": \"Bornyasherk\",\n \"latitude\": 63.416667,\n \"longitude\": 10.416667,\n \"timezone\": \"Europe/Bornyasherk\",\n \"asn\": \"AS59795\",\n \"asn_org\": \"Hosting4Real\",\n \"hostname\": \"localhost\",\n \"user_agent\": {\n \"product\": \"curl\",\n \"version\": \"7.2.6.0\",\n \"raw_value\": \"curl/7.2.6.0\"\n }\n}", 200},
|
||||||
{s.URL + "/port/foo", "{\n \"status\": 400,\n \"error\": \"invalid port: foo\"\n}", 400},
|
{s.URL + "/port/foo", "{\n \"status\": 400,\n \"error\": \"invalid port: foo\"\n}", 400},
|
||||||
{s.URL + "/port/0", "{\n \"status\": 400,\n \"error\": \"invalid port: 0\"\n}", 400},
|
{s.URL + "/port/0", "{\n \"status\": 400,\n \"error\": \"invalid port: 0\"\n}", 400},
|
||||||
{s.URL + "/port/65537", "{\n \"status\": 400,\n \"error\": \"invalid port: 65537\"\n}", 400},
|
{s.URL + "/port/65537", "{\n \"status\": 400,\n \"error\": \"invalid port: 65537\"\n}", 400},
|
||||||
|
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/mpolden/echoip/iputil"
|
"github.com/levelsoftware/echoip/iputil"
|
||||||
parser "github.com/mpolden/echoip/iputil/paser"
|
parser "github.com/levelsoftware/echoip/iputil/paser"
|
||||||
geoip2 "github.com/oschwald/geoip2-golang"
|
geoip2 "github.com/oschwald/geoip2-golang"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -84,22 +84,24 @@ func (g *geoip) Parse(ip net.IP, hostname string) (parser.Response, error) {
|
||||||
UsingGeoIP: true,
|
UsingGeoIP: true,
|
||||||
UsingIPStack: false,
|
UsingIPStack: false,
|
||||||
IPStackSecurityEnabled: false,
|
IPStackSecurityEnabled: false,
|
||||||
IP: ip,
|
|
||||||
IPDecimal: ipDecimal,
|
/* kept for backward compatibility */
|
||||||
Country: country.Name,
|
IP: ip,
|
||||||
CountryISO: country.ISO,
|
IPDecimal: ipDecimal,
|
||||||
CountryEU: country.IsEU,
|
Country: country.Name,
|
||||||
RegionName: city.RegionName,
|
CountryISO: country.ISO,
|
||||||
RegionCode: city.RegionCode,
|
CountryEU: country.IsEU,
|
||||||
MetroCode: city.MetroCode,
|
RegionName: city.RegionName,
|
||||||
PostalCode: city.PostalCode,
|
RegionCode: city.RegionCode,
|
||||||
City: city.Name,
|
MetroCode: city.MetroCode,
|
||||||
Latitude: city.Latitude,
|
PostalCode: city.PostalCode,
|
||||||
Longitude: city.Longitude,
|
City: city.Name,
|
||||||
Timezone: city.Timezone,
|
Latitude: city.Latitude,
|
||||||
ASN: autonomousSystemNumber,
|
Longitude: city.Longitude,
|
||||||
ASNOrg: asn.AutonomousSystemOrganization,
|
Timezone: city.Timezone,
|
||||||
Hostname: hostname,
|
ASN: autonomousSystemNumber,
|
||||||
|
ASNOrg: asn.AutonomousSystemOrganization,
|
||||||
|
Hostname: hostname,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,11 @@ package ipstack
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"reflect"
|
"time"
|
||||||
|
|
||||||
|
"github.com/levelsoftware/echoip/iputil"
|
||||||
|
parser "github.com/levelsoftware/echoip/iputil/paser"
|
||||||
|
|
||||||
"github.com/mpolden/echoip/iputil"
|
|
||||||
parser "github.com/mpolden/echoip/iputil/paser"
|
|
||||||
"github.com/qioalice/ipstack"
|
"github.com/qioalice/ipstack"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,6 +18,7 @@ type IPStack struct {
|
||||||
func (ips *IPStack) Parse(ip net.IP, hostname string) (parser.Response, error) {
|
func (ips *IPStack) Parse(ip net.IP, hostname string) (parser.Response, error) {
|
||||||
res, err := ipstack.IP(ip.String())
|
res, err := ipstack.IP(ip.String())
|
||||||
ips.response = res
|
ips.response = res
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return parser.Response{}, err
|
return parser.Response{}, err
|
||||||
}
|
}
|
||||||
|
@ -26,52 +28,91 @@ func (ips *IPStack) Parse(ip net.IP, hostname string) (parser.Response, error) {
|
||||||
parserResponse := parser.Response{
|
parserResponse := parser.Response{
|
||||||
UsingGeoIP: false,
|
UsingGeoIP: false,
|
||||||
UsingIPStack: true,
|
UsingIPStack: true,
|
||||||
Latitude: float64(res.Latitide),
|
|
||||||
Longitude: float64(res.Longitude),
|
/* kept for backward compatibility */
|
||||||
Hostname: hostname,
|
Latitude: float64(res.Latitide),
|
||||||
IP: ip,
|
Longitude: float64(res.Longitude),
|
||||||
IPDecimal: ipDecimal,
|
Hostname: hostname,
|
||||||
Country: res.CountryName,
|
IP: ip,
|
||||||
CountryISO: res.CountryCode,
|
IPDecimal: ipDecimal,
|
||||||
RegionName: res.RegionName,
|
Country: res.CountryName,
|
||||||
RegionCode: res.RegionCode,
|
CountryISO: res.CountryCode,
|
||||||
MetroCode: 0,
|
RegionName: res.RegionName,
|
||||||
PostalCode: res.Zip,
|
RegionCode: res.RegionCode,
|
||||||
City: res.City,
|
MetroCode: 0,
|
||||||
|
PostalCode: res.Zip,
|
||||||
|
City: res.City,
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.Timezone != nil {
|
ips.ParseSecurityResponse(&parserResponse)
|
||||||
parserResponse.Timezone = res.Timezone.ID
|
ips.ParseTimezoneResponse(&parserResponse)
|
||||||
parserResponse.IsDayLightSavings = res.Timezone.IsDaylightSaving
|
ips.ParseLocationResponse(&parserResponse)
|
||||||
}
|
ips.ParseConnectionResponse(&parserResponse)
|
||||||
|
|
||||||
if res.Security != nil {
|
|
||||||
parserResponse.IPStackSecurityEnabled = true
|
|
||||||
parserResponse.IsProxy = res.Security.IsProxy
|
|
||||||
parserResponse.IsCrawler = res.Security.IsCrawler
|
|
||||||
parserResponse.CrawlerName = res.Security.CrawlerName
|
|
||||||
parserResponse.CrawlerType = res.Security.CrawlerType
|
|
||||||
parserResponse.IsTor = res.Security.IsTOR
|
|
||||||
parserResponse.ThreatLevel = res.Security.ThreatLevel
|
|
||||||
|
|
||||||
if !reflect.ValueOf(&res.Security.ThreatTypes).IsNil() {
|
|
||||||
parserResponse.ThreatTypes = &res.Security.ThreatTypes
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
return parserResponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ips *IPStack) ParseSecurityResponse(parserResponse *parser.Response) {
|
||||||
|
if ips.response.Security != nil {
|
||||||
|
parserResponse.IPStackSecurityEnabled = true
|
||||||
|
|
||||||
|
parserResponse.Security = parser.Security{
|
||||||
|
IsProxy: ips.response.Security.IsProxy,
|
||||||
|
IsTor: ips.response.Security.IsTOR,
|
||||||
|
CrawlerName: ips.response.Security.CrawlerName,
|
||||||
|
CrawlerType: ips.response.Security.CrawlerType,
|
||||||
|
ThreatLevel: ips.response.Security.ThreatLevel,
|
||||||
|
ThreatTypes: ips.response.Security.ThreatTypes.([]string),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ips *IPStack) ParseTimezoneResponse(parserResponse *parser.Response) {
|
||||||
|
if ips.response.Timezone != nil {
|
||||||
|
parserResponse.TimezoneEtc = parser.Timezone{
|
||||||
|
ID: ips.response.Timezone.ID,
|
||||||
|
CurrentTime: ips.response.Timezone.CurrentTime.Format(time.RFC3339),
|
||||||
|
GmtOffset: ips.response.Timezone.GMTOffset,
|
||||||
|
Code: ips.response.Timezone.Code,
|
||||||
|
IsDaylightSavings: ips.response.Timezone.IsDaylightSaving,
|
||||||
|
}
|
||||||
|
|
||||||
|
/* kept for backward compatibility */
|
||||||
|
parserResponse.Timezone = ips.response.Timezone.ID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ips *IPStack) ParseLocationResponse(parserResponse *parser.Response) {
|
||||||
|
if ips.response.Location != nil {
|
||||||
|
var languages []parser.Language
|
||||||
|
for i := 0; i < len(ips.response.Location.Languages); i++ {
|
||||||
|
languages = append(languages, parser.Language{
|
||||||
|
Code: ips.response.Location.Languages[i].Code,
|
||||||
|
Name: ips.response.Location.Languages[i].Name,
|
||||||
|
Native: ips.response.Location.Languages[i].NativeName,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
parserResponse.Location = parser.Location{
|
||||||
|
Languages: languages,
|
||||||
|
CountryFlag: parser.CountryFlag{
|
||||||
|
Flag: ips.response.Location.CountryFlagLink,
|
||||||
|
Emoji: ips.response.Location.CountryFlagEmoji,
|
||||||
|
EmojiUnicode: ips.response.Location.CountryFlagEmojiUnicode,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/* kept for backward compatibility */
|
||||||
|
parserResponse.CountryEU = &ips.response.Location.IsEU
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ips *IPStack) ParseConnectionResponse(parserResponse *parser.Response) {
|
||||||
|
if ips.response.Connection != nil && ips.response.Connection.ASN > 0 {
|
||||||
|
/* kept for backward compatibility */
|
||||||
|
parserResponse.ASN = fmt.Sprintf("AS%d", ips.response.Connection.ASN)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (ips *IPStack) IsEmpty() bool {
|
func (ips *IPStack) IsEmpty() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/mpolden/echoip/useragent"
|
"github.com/levelsoftware/echoip/useragent"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Parser interface {
|
type Parser interface {
|
||||||
|
@ -12,34 +12,75 @@ type Parser interface {
|
||||||
IsEmpty() bool
|
IsEmpty() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Response struct {
|
type Currency struct {
|
||||||
UsingGeoIP bool `json:"UsingGeoIP"`
|
Code string `json:"code,omitempty"`
|
||||||
UsingIPStack bool `json:"UsingIPStack"`
|
Name string `json:"name,omitempty"`
|
||||||
IPStackSecurityEnabled bool `json:"IPStackSecurityEnabled"`
|
Plural string `json:"plural,omitempty"`
|
||||||
IP net.IP `json:"ip"`
|
Symbol string `json:"symbol,omitempty"`
|
||||||
IPDecimal *big.Int `json:"ip_decimal"`
|
SymbolNative string `json:"symbol_native,omitempty"`
|
||||||
Country string `json:"country,omitempty"`
|
}
|
||||||
CountryISO string `json:"country_iso,omitempty"`
|
|
||||||
CountryEU *bool `json:"country_eu,omitempty"`
|
type Security struct {
|
||||||
RegionName string `json:"region_name,omitempty"`
|
IsProxy bool `json:"is_proxy"`
|
||||||
RegionCode string `json:"region_code,omitempty"`
|
IsCrawler bool `json:"is_crawler"`
|
||||||
MetroCode uint `json:"metro_code,omitempty"`
|
CrawlerName string `json:"crawler_name,omitempty"`
|
||||||
PostalCode string `json:"zip_code,omitempty"`
|
CrawlerType string `json:"crawler_type,omitempty"`
|
||||||
City string `json:"city,omitempty"`
|
IsTor bool `json:"is_tor"`
|
||||||
Latitude float64 `json:"latitude,omitempty"`
|
ThreatLevel string `json:"threat_level,omitempty"`
|
||||||
Longitude float64 `json:"longitude,omitempty"`
|
ThreatTypes []string `json:"threat_types,omitempty"`
|
||||||
Timezone string `json:"time_zone,omitempty"`
|
}
|
||||||
IsDayLightSavings bool `json:"is_daylight_savings,omitempty"`
|
|
||||||
ASN string `json:"asn,omitempty"`
|
type Timezone struct {
|
||||||
ASNOrg string `json:"asn_org,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
Hostname string `json:"hostname,omitempty"`
|
CurrentTime string `json:"current_time,omitempty"`
|
||||||
UserAgent *useragent.UserAgent `json:"user_agent,omitempty"`
|
GmtOffset int `json:"gmt_offset,omitempty"`
|
||||||
CurrencyCode string `json:"currency_code,omitempty"`
|
Code string `json:"code,omitempty"`
|
||||||
IsProxy bool `json:"is_proxy,omitempty"`
|
IsDaylightSavings bool `json:"is_daylight_savings,omitempty"`
|
||||||
IsCrawler bool `json:"is_crawler,omitempty"`
|
}
|
||||||
CrawlerName string `json:"crawler_name,omitempty"`
|
|
||||||
CrawlerType string `json:"crawler_type,omitempty"`
|
type Language struct {
|
||||||
IsTor bool `json:"is_tor,omitempty"`
|
Code string `json:"code,omitempty"`
|
||||||
ThreatLevel string `json:"threat_level,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
ThreatTypes *interface{} `json:"threat_types,omitempty"`
|
Native string `json:"native,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CountryFlag struct {
|
||||||
|
Flag string `json:"flag,omitempty"`
|
||||||
|
Emoji string `json:"emoji,omitempty"`
|
||||||
|
EmojiUnicode string `json:"emoji_unicode,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Location struct {
|
||||||
|
Languages interface{} `json:"languages,omitempty"`
|
||||||
|
CountryFlag CountryFlag `json:"country_flag,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Response struct {
|
||||||
|
UsingGeoIP bool `json:"UsingGeoIP"`
|
||||||
|
UsingIPStack bool `json:"UsingIPStack"`
|
||||||
|
IPStackSecurityEnabled bool `json:"IPStackSecurityEnabled"`
|
||||||
|
|
||||||
|
TimezoneEtc Timezone `json:"timezone_etc,omitempty"`
|
||||||
|
Security Security `json:"security,omitempty"`
|
||||||
|
Currency Currency `json:"currency,omitempty"`
|
||||||
|
Location Location `json:"location,omitempty"`
|
||||||
|
|
||||||
|
/* Kept to prevent breaking changes */
|
||||||
|
IP net.IP `json:"ip"`
|
||||||
|
IPDecimal *big.Int `json:"ip_decimal"`
|
||||||
|
Country string `json:"country,omitempty"`
|
||||||
|
CountryISO string `json:"country_iso,omitempty"`
|
||||||
|
CountryEU *bool `json:"country_eu,omitempty"`
|
||||||
|
RegionName string `json:"region_name,omitempty"`
|
||||||
|
RegionCode string `json:"region_code,omitempty"`
|
||||||
|
MetroCode uint `json:"metro_code,omitempty"`
|
||||||
|
PostalCode string `json:"zip_code,omitempty"`
|
||||||
|
City string `json:"city,omitempty"`
|
||||||
|
Latitude float64 `json:"latitude,omitempty"`
|
||||||
|
Longitude float64 `json:"longitude,omitempty"`
|
||||||
|
Timezone string `json:"timezone,omitempty"`
|
||||||
|
ASN string `json:"asn,omitempty"`
|
||||||
|
ASNOrg string `json:"asn_org,omitempty"`
|
||||||
|
Hostname string `json:"hostname,omitempty"`
|
||||||
|
UserAgent *useragent.UserAgent `json:"user_agent,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue