github.com/richardwilkes/toolbox@v1.121.0/xio/network/external_ip.go (about) 1 // Copyright (c) 2016-2024 by Richard A. Wilkes. All rights reserved. 2 // 3 // This Source Code Form is subject to the terms of the Mozilla Public 4 // License, version 2.0. If a copy of the MPL was not distributed with 5 // this file, You can obtain one at http://mozilla.org/MPL/2.0/. 6 // 7 // This Source Code Form is "Incompatible With Secondary Licenses", as 8 // defined by the Mozilla Public License, version 2.0. 9 10 package network 11 12 import ( 13 "io" 14 "net" 15 "net/http" 16 "strings" 17 "time" 18 19 "github.com/richardwilkes/toolbox/xio" 20 ) 21 22 var sites = []string{ 23 // These seem to prefer ipv4 responses, if possible 24 "http://whatismyip.akamai.com/", 25 "https://myip.dnsomatic.com/", 26 "http://api.ipify.org/", 27 "http://checkip.amazonaws.com/", 28 29 // These seem to prefer ipv6 responses, if possible 30 "http://icanhazip.com/", 31 "https://myexternalip.com/raw", 32 "http://ifconfig.io/ip", 33 "http://ident.me/", 34 } 35 36 // ExternalIP returns your IP address as seen by external sites. It does this by iterating through a list of websites 37 // that will return your IP address as they see it. The first response with a valid IP address will be returned. timeout 38 // sets the maximum amount of time for each attempt. 39 func ExternalIP(timeout time.Duration) string { 40 client := &http.Client{Timeout: timeout} 41 for _, site := range sites { 42 if ip := externalIP(client, site); ip != "" { 43 return ip 44 } 45 } 46 return "" 47 } 48 49 func externalIP(client *http.Client, site string) string { 50 if resp, err := client.Get(site); err == nil { //nolint:noctx // The timeout on the client provides the same effect 51 defer xio.DiscardAndCloseIgnoringErrors(resp.Body) 52 var body []byte 53 if body, err = io.ReadAll(resp.Body); err == nil { 54 if ip := net.ParseIP(strings.TrimSpace(string(body))); ip != nil { 55 return ip.String() 56 } 57 } 58 } 59 return "" 60 }