-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
130 lines (112 loc) · 2.92 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package main
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
)
var client *http.Client
func init() {
client = &http.Client{}
}
func main() {
var batch BatchRequest
flag.Var(&batch, "batch", "Pass a comma separated list of IPs to process multiple IPs simultaneously")
flag.Parse()
if len(os.Args) < 2 {
fmt.Println("No IP specified, please add an IP an try again")
os.Exit(1)
}
if len(flag.Args()) > 0 && len(batch) > 0 {
fmt.Println("Cannot combine individual IP requests and batch requests simultaneously\nIf you meant to do only a batch request please try again with IPs being comma separated.\nIf you meant to pass a single IP then rerun the comman without the batch flag")
os.Exit(1)
}
if len(batch) > 0 {
for _, ip := range batch {
doRequest(ip)
}
} else {
ip := os.Args[1]
doRequest(ip)
}
}
type IpResponse struct {
Query string `json:"query"`
Status string `json:"status"`
Country string `json:"country"`
CountryCode string `json:"countryCode"`
Region string `json:"region"`
RegionName string `json:"regionName"`
City string `json:"city"`
Zip string `json:"zip"`
Lat float64 `json:"lat"`
Lon float64 `json:"lon"`
Timezone string `json:"timezone"`
Isp string `json:"isp"`
Org string `json:"org"`
As string `json:"as"`
}
type IpFail struct {
Status string `json:"status"`
Message string `json:"message"`
Query string `json:"query"`
}
type DetermineSuccess struct {
Status string `json:"status"`
}
func PrintSuccess(ip IpResponse) {
fmt.Fprintf(os.Stdout, "\nQueried IP: %s\nCountry of Origin: %s\nISP: %s\nASN: %s\n\n", ip.Query, ip.Country, ip.Isp, ip.As)
}
func PrintError(ipErr IpFail) {
fmt.Fprintf(os.Stdout, "\nFailed Request!\nStatus: %s\nMessage: %s\nQuery: %s\n\n", ipErr.Status, ipErr.Message, ipErr.Query)
}
type BatchRequest []string
func (br *BatchRequest) Set(s string) error {
*br = strings.Split(s, ",")
return nil
}
func (br *BatchRequest) String() string {
return fmt.Sprintln(*br)
}
func doRequest(ip string) {
req, err := http.NewRequest("GET", fmt.Sprintf("http://ip-api.com/json/%s", ip), nil)
if err != nil {
fmt.Println("Malformed request: ", err)
os.Exit(1)
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Accept", "application/json")
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error returned from API: ", err)
os.Exit(1)
}
body, err := ioutil.ReadAll(resp.Body)
defer resp.Body.Close()
if err != nil {
panic(err)
}
var success DetermineSuccess
err = json.Unmarshal(body, &success)
if err != nil {
panic(err)
}
if success.Status == "fail" {
var apiErr IpFail
err := json.Unmarshal(body, &apiErr)
if err != nil {
panic(err)
}
PrintError(apiErr)
os.Exit(1)
}
var ipData IpResponse
err = json.Unmarshal(body, &ipData)
if err != nil {
panic(err)
}
PrintSuccess(ipData)
}