title: How can I fetch the client IPv4 address in Go?
body: <p>I am trying to write a function that returns the client IPv4 address.</p>
  
  <p>I fetch the string from <code>http.Request.RemoteAddr</code> and filter out the ip with <code>net.SplitHostPort</code>. This gives me ::1 because I am on localhost which I asume is supposed to be an IPv6 address?</p>
  
  <p>then I do <code>ip := net.ParseIP(s)</code> and then <code>ip = ip.To4()</code> to get the IPv4 address.</p>
  
  <p>I am on Windows and have this in my hosts file: (The rest is commented out.)</p>
  
  <pre><code>127.0.0.1 localhost localhost.com www.localhost.com *.localhost.com
  </code></pre>
  
  <p>Basically I expect to get 127.0.0.1, but I can't get it.</p>
  
  <p>This is the code:</p>
  
  <pre><code>func FilterIpv4(r *http.Request) (string, error) {
      var s string
      // if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
      //  ip = xff
      // }
      s, _, err := net.SplitHostPort(r.RemoteAddr)
      if err != nil {
          return "", err
      }
      ip := net.ParseIP(s)
      ip = ip.To4()
      spew.Dump(ip.String()) // outputs "&lt;nil&gt;"
      return "", nil
  
  }
  </code></pre>
  
  <p>EDIT:</p>
  
  <p>I don't know if it is a good idea to do this but atleast I get the ipv4 addresses now. Maybe I should just stick to ipv6? I don't know about this. But replacing this code:</p>
  
  <pre><code>log.Fatal(http.ListenAndServe(":"+config.SrvPort, router))
  </code></pre>
  
  <p>With this:</p>
  
  <pre><code>ln, err := net.Listen("tcp4", ":"+config.SrvPort)
  if err != nil {
      log.Fatal(err)
  }
  log.Fatal(http.Serve(ln, router))
  </code></pre>
  
  <p>Made it possible for me to get the ipv4 address.</p>
  
  <p>Does someone know if this is a good idea in general? Or should I stick to ipv6 addresses?</p>
  
  <p>EDIT 2:</p>
  
  <p>I ended up with this function:</p>
  
  <pre><code>func FilterIP(r *http.Request) (string, error) {
      var ip string
      var err error
      if xff := r.Header.Get("X-Forwarded-For"); xff != "" {
          ips := strings.Split(xff, ", ")
          ip = ips[0]
      } else {
          ip, _, err = net.SplitHostPort(r.RemoteAddr)
          if err != nil {
              return "", err
          }
      }
      if !IsIP(ip) {
          return "", err
      }
      return ip, nil
  }
  </code></pre>
  
  <p>I will save both ipv6 and ipv4 addresses.</p>