1// Package ipify provides a single function for retrieving your computer's
2// public IP address from the ipify service: http://www.ipify.org
3package ipify
4
5import (
6	"errors"
7	"github.com/jpillora/backoff"
8	"io/ioutil"
9	"net/http"
10	"strconv"
11	"time"
12)
13
14// GetIp queries the ipify service (http://www.ipify.org) to retrieve this
15// machine's public IP address.  Returns your public IP address as a string, and
16// any error encountered.  By default, this function will run using exponential
17// backoff -- if this function fails for any reason, the request will be retried
18// up to 3 times.
19//
20// Usage:
21//
22//		package main
23//
24//		import (
25//			"fmt"
26//			"github.com/rdegges/go-ipify"
27//		)
28//
29//		func main() {
30//			ip, err := ipify.GetIp()
31//			if err != nil {
32//				fmt.Println("Couldn't get my IP address:", err)
33//			} else {
34//				fmt.Println("My IP address is:", ip)
35//			}
36//		}
37func GetIp() (string, error) {
38	b := &backoff.Backoff{
39		Jitter: true,
40	}
41	client := &http.Client{}
42
43	req, err := http.NewRequest("GET", API_URI, nil)
44	if err != nil {
45		return "", errors.New("Received an invalid status code from ipify: 500. The service might be experiencing issues.")
46	}
47
48	req.Header.Add("User-Agent", USER_AGENT)
49
50	for tries := 0; tries < MAX_TRIES; tries++ {
51		resp, err := client.Do(req)
52		if err != nil {
53			d := b.Duration()
54			time.Sleep(d)
55			continue
56		}
57
58		defer resp.Body.Close()
59
60		ip, err := ioutil.ReadAll(resp.Body)
61		if err != nil {
62			return "", errors.New("Received an invalid status code from ipify: 500. The service might be experiencing issues.")
63		}
64
65		if resp.StatusCode != 200 {
66			return "", errors.New("Received an invalid status code from ipify: " + strconv.Itoa(resp.StatusCode) + ". The service might be experiencing issues.")
67		}
68
69		return string(ip), nil
70	}
71
72	return "", errors.New("The request failed because it wasn't able to reach the ipify service. This is most likely due to a networking error of some sort.")
73}
74