Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 0 additions & 27 deletions Gopkg.lock

This file was deleted.

29 changes: 0 additions & 29 deletions Gopkg.toml

This file was deleted.

3 changes: 1 addition & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
test: vet lint staticcheck tests

prebuild:
go get -u github.com/golang/dep/cmd/dep \
golang.org/x/lint/golint \
go get -u golang.org/x/lint/golint \
honnef.co/go/tools/cmd/staticcheck \
golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow

Expand Down
16 changes: 7 additions & 9 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/url"
Expand Down Expand Up @@ -92,7 +91,7 @@ func (c Client) RawLookupWithContext(ctx context.Context, ip string) (*http.Resp
return resp, nil
default:
// provide response body as error to consumer
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrapf(err, "failed to read body from response with status code %q: %s", resp.Status, err)
}
Expand All @@ -108,7 +107,7 @@ func (c Client) RawLookupWithContext(ctx context.Context, ip string) (*http.Resp
}

func decodeIP(r io.Reader) (IP, error) {
body, err := ioutil.ReadAll(r)
body, err := io.ReadAll(r)
if err != nil {
return IP{}, err
}
Expand Down Expand Up @@ -137,7 +136,7 @@ func (c Client) LookupWithContext(ctx context.Context, ip string) (IP, error) {
}

defer func() {
_, _ = io.Copy(ioutil.Discard, resp.Body)
_, _ = io.Copy(io.Discard, resp.Body)
_ = resp.Body.Close()
}()

Expand Down Expand Up @@ -179,7 +178,7 @@ func (c *Client) RawBulkLookup(ips []string) (*http.Response, error) {
}

// RawBulkLookupWithContext is a RawBulkLookup with a provided context.Context.
func (c *Client) RawBulkLookupWithContext(ctx context.Context, ips []string) (*http.Response, error) {
func (c *Client) RawBulkLookupWithContext(ctx context.Context, ips []string) (*http.Response, error) {
// build request
req, err := newBulkPostRequestWithContext(ctx, c.e+"bulk", c.k, ips)
if err != nil {
Expand All @@ -198,7 +197,7 @@ func (c *Client) RawBulkLookup(ips []string) (*http.Response, error) {
return resp, nil
default:
// provide response body as error to consumer
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrapf(err, "failed to read body from response with status code %q: %s", resp.Status, err)
}
Expand Down Expand Up @@ -272,11 +271,11 @@ func (c *Client) BulkLookupWithContext(ctx context.Context, ips []string) ([]*IP
}

defer func() {
_, _ = io.Copy(ioutil.Discard, resp.Body)
_, _ = io.Copy(io.Discard, resp.Body)
_ = resp.Body.Close()
}()

body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, errors.Wrap(err, "failed to read response body")
}
Expand Down Expand Up @@ -317,7 +316,6 @@ func newHTTPClient() *http.Client {
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 60 * time.Second,
Expand Down
115 changes: 103 additions & 12 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"net/http/httptest"
Expand Down Expand Up @@ -78,7 +77,7 @@ func testBulkHTTPServer() *httptest.Server {
return
}

body, err := ioutil.ReadAll(r.Body)
body, err := io.ReadAll(r.Body)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintf(w, "failed to read body: %v", err)
Expand Down Expand Up @@ -452,8 +451,54 @@ func Test_client_Lookup(t *testing.T) {
t.Errorf("ip.TimeZone = %#v, want %#v", a, b)
}

if a, b := *ip.Threat, *tt.o.Threat; a != b {
t.Errorf("ip.Threat = %#v, want %#v", a, b)
if a, b := ip.Threat.IsThreat, tt.o.Threat.IsThreat; a != b {
t.Errorf("ip.Threat.IsThreat = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsBogon, tt.o.Threat.IsBogon; a != b {
t.Errorf("ip.Threat.IsBogon = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsAnonymous, tt.o.Threat.IsAnonymous; a != b {
t.Errorf("ip.Threat.IsAnonymous = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsDatacenter, tt.o.Threat.IsDatacenter; a != b {
t.Errorf("ip.Threat.IsDatacenter = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsProxy, tt.o.Threat.IsProxy; a != b {
t.Errorf("ip.Threat.IsProxy = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsICloudRelay, tt.o.Threat.IsICloudRelay; a != b {
t.Errorf("ip.Threat.IsICloudRelay = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsKnownAbuser, tt.o.Threat.IsKnownAbuser; a != b {
t.Errorf("ip.Threat.IsKnownAbuser = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsKnownAttacker, tt.o.Threat.IsKnownAttacker; a != b {
t.Errorf("ip.Threat.IsKnownAttacker = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsTOR, tt.o.Threat.IsTOR; a != b {
t.Errorf("ip.Threat.IsTOR = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsVPN, tt.o.Threat.IsVPN; a != b {
t.Errorf("ip.Threat.IsVPN = %#v, want %#v", a, b)
}

if a, b := ip.Threat.Blocklists, tt.o.Threat.Blocklists; len(a) == len(b) {
for i := 0; i < len(a); i++ {
if a[i] != b[i] {
t.Errorf("ip.Threat.Blocklists[%d] = %#v, want %#v", i, a[i], b[i])
}
}
} else {
t.Errorf("len(ip.Threat.Blocklists) = %#v, want %#v", len(a), len(b))
}
})
}
Expand Down Expand Up @@ -559,11 +604,11 @@ func Test_client_RawLookup(t *testing.T) {
}

defer func() {
_, _ = io.Copy(ioutil.Discard, resp.Body)
_, _ = io.Copy(io.Discard, resp.Body)
_ = resp.Body.Close()
}()

body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
t.Fatalf("unexpected error reading response body: %s", err)
}
Expand Down Expand Up @@ -888,8 +933,54 @@ func Test_decodeIP(t *testing.T) {
t.Errorf("ip.TimeZone = %#v, want %#v", a, b)
}

if a, b := *ip.Threat, *tt.o.Threat; a != b {
t.Errorf("ip.Threat = %#v, want %#v", a, b)
if a, b := ip.Threat.IsThreat, tt.o.Threat.IsThreat; a != b {
t.Errorf("ip.Threat.IsThreat = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsBogon, tt.o.Threat.IsBogon; a != b {
t.Errorf("ip.Threat.IsBogon = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsAnonymous, tt.o.Threat.IsAnonymous; a != b {
t.Errorf("ip.Threat.IsAnonymous = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsDatacenter, tt.o.Threat.IsDatacenter; a != b {
t.Errorf("ip.Threat.IsDatacenter = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsProxy, tt.o.Threat.IsProxy; a != b {
t.Errorf("ip.Threat.IsProxy = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsICloudRelay, tt.o.Threat.IsICloudRelay; a != b {
t.Errorf("ip.Threat.IsICloudRelay = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsKnownAbuser, tt.o.Threat.IsKnownAbuser; a != b {
t.Errorf("ip.Threat.IsKnownAbuser = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsKnownAttacker, tt.o.Threat.IsKnownAttacker; a != b {
t.Errorf("ip.Threat.IsKnownAttacker = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsTOR, tt.o.Threat.IsTOR; a != b {
t.Errorf("ip.Threat.IsTOR = %#v, want %#v", a, b)
}

if a, b := ip.Threat.IsVPN, tt.o.Threat.IsVPN; a != b {
t.Errorf("ip.Threat.IsVPN = %#v, want %#v", a, b)
}

if a, b := ip.Threat.Blocklists, tt.o.Threat.Blocklists; len(a) == len(b) {
for i := 0; i < len(a); i++ {
if a[i] != b[i] {
t.Errorf("ip.Threat.Blocklists[%d] = %#v, want %#v", i, a[i], b[i])
}
}
} else {
t.Errorf("len(ip.Threat.Blocklists) = %#v, want %#v", len(a), len(b))
}
})
}
Expand Down Expand Up @@ -931,7 +1022,7 @@ func TestClient_RawBulkLookup(t *testing.T) {
{
name: "bad_host",
ips: []string{"1.1.1.1", "8.8.8.8"},
err: `http request to "http://127.0.0.1:9085/bulk" failed: Post http://127.0.0.1:9085/bulk?api-key=badAPIkey: dial tcp 127.0.0.1:9085: connect: connection refused`,
err: `http request to "http://127.0.0.1:9085/bulk" failed: Post "http://127.0.0.1:9085/bulk?api-key=badAPIkey": dial tcp 127.0.0.1:9085: connect: connection refused`,
},
{
name: "bad_api_key",
Expand Down Expand Up @@ -975,16 +1066,16 @@ func TestClient_RawBulkLookup(t *testing.T) {
}

defer func() {
_, _ = io.Copy(ioutil.Discard, got.Body)
_, _ = io.Copy(io.Discard, got.Body)
_ = got.Body.Close()
}()

if got.StatusCode != tt.wantStatus {
t.Fatalf("got.StatusCode = %d, want %d", got.StatusCode, tt.wantStatus)
}

body, err := ioutil.ReadAll(got.Body)
testErrCheck(t, "ioutil.ReadAll()", "", err)
body, err := io.ReadAll(got.Body)
testErrCheck(t, "io.ReadAll()", "", err)

if b := string(body); b != tt.wantBody {
t.Fatalf("got.Body = %q, want %q", b, tt.wantBody)
Expand Down
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module github.com/ipdata/go

go 1.22.3

require (
github.com/google/go-cmp v0.6.0
github.com/pkg/errors v0.9.1
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
41 changes: 21 additions & 20 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,32 +94,33 @@ type TimeZone struct {
// Threat represents the threat object within the JSON response from the API.
// This provides information about what type of threat this IP may be.
type Threat struct {
IsTOR bool `json:"is_tor"`
IsVPN bool `json:"is_vpn"`
IsICloudRelay bool `json:"is_icloud_relay"`
IsProxy bool `json:"is_proxy"`
IsDatacenter bool `json:"is_datacenter"`
IsAnonymous bool `json:"is_anonymous"`
IsKnownAttacker bool `json:"is_known_attacker"`
IsKnownAbuser bool `json:"is_known_abuser"`
IsThreat bool `json:"is_threat"`
IsBogon bool `json:"is_bogon"`
Blocklists []Blocklist `json:"blocklists"`
Scores Scores `json:"scores"`
IsTOR bool `json:"is_tor"`
IsVPN bool `json:"is_vpn"`
IsICloudRelay bool `json:"is_icloud_relay"`
IsProxy bool `json:"is_proxy"`
IsDatacenter bool `json:"is_datacenter"`
IsAnonymous bool `json:"is_anonymous"`
IsKnownAttacker bool `json:"is_known_attacker"`
IsKnownAbuser bool `json:"is_known_abuser"`
IsThreat bool `json:"is_threat"`
IsBogon bool `json:"is_bogon"`
Blocklists []Blocklist `json:"blocklists"`
Scores Scores `json:"scores"`
}

// Blocklist includes details of blocklists that have been attributed to an IP
type Blocklist struct {
Name string `json:"name"`
Site string `json:"site"`
Type string `json:"type"`
Name string `json:"name"`
Site string `json:"site"`
Type string `json:"type"`
}


// Scores represents scores from IP reputation
type Scores struct {
VPNScore int `json:"vpn_score"`
ProxyScore int `json:"proxy_score"`
ThreatScore int `json:"threat_score"`
TrustScore int `json:"trust_score"`
VPNScore int `json:"vpn_score"`
ProxyScore int `json:"proxy_score"`
ThreatScore int `json:"threat_score"`
TrustScore int `json:"trust_score"`
}

type bulkIP struct {
Expand Down
Loading