Fragment Description:

Using http.Request to find the client IP address.
Request contains the field 'RemoteAddress'.
The net package proposes the function:
'SplitHostPort' signature:
func SplitHostPort(hostport string) (host, port string, err error) SplitHostPort splits a network address of the form 'host:port', '[host]:port' or '[ipv6-host%zone]:port' into host or ipv6-host%zone and port.
A literal address or host name for IPv6 must be enclosed in square brackets, as in '[::1]:80', '[ipv6-host]:http' or '[ipv6-host%zone]:80'.
The net package helps us parse the result generated by 'SplitHostPort' with the function 'ParseIP'.


Last update, on 2015, Tue 1 Dec, 20:17:58

/* ... <== see fragment description ... */

package main

import (

func IndexPage(w http.ResponseWriter, r *http.Request) {
    // get client IP address
    ip, port, err := net.SplitHostPort(r.RemoteAddr)
    if err != nil {
        log.Print("userIP: [", r.RemoteAddr, "] is not IP:port")
    userIP := net.ParseIP(ip)
    if userIP == nil {
        log.Print("userIP: [", r.RemoteAddr, "] is not IP:port")
    fmt.Fprintf(w, "<p>IP: %s</p>", ip)
    fmt.Fprintf(w, "<p>Port: %s</p>", port)

    // The user could acccess the web server via a proxy or load balancer.
    // The above IP address will be the IP address of the proxy or load balancer
    // and not the user's machine. Let's read the r.header "X-Forwarded-For (XFF)".
    // In our example the value returned is nil, we consider there is no proxy,
    // the IP indicates the user's address.
    // WARNING: this header is optional and will only be defined when site is
    // accessed via non-anonymous proxy and takes precedence over RemoteAddr.
    // (read before any further use).
    proxied := r.Header.Get("X-FORWARDED-FOR")
    if proxied != "" {
        fmt.Fprintf(w, "<p>Forwarded for: %s</p>", proxied)
    fmt.Fprint(w, "<p>X-Forwarded-For : indicates this is the user's address (no proxy)<p>\n")

func main() {
    http.HandleFunc("/", IndexPage)

    log.Print("Listening on port: 8080...")
    http.ListenAndServe(":8080", nil)