I'm using golang http package. How could the server limit client IP address?
func (s *Worker) Run(c chan error) {
    apiMux := http.NewServeMux()
    apiMux.HandleFunc("/test", s.test)
    apiMux.HandleFunc("/block/create", s.CreateBlock)
    apiMux.HandleFunc("/block/delete", s.DeleteBlock)
    apiServer := &http.Server{
        Addr:    "0.0.0.0:" + strconv.Itoa(s.ListenPort),
        Handler: apiMux,
    }
    go func() {
        log.Println("Worker listening on " + apiServer.Addr)
        c <- apiServer.ListenAndServe()
    }()
}
                The http package in GoLang allows HTTP functions to be carried out in GoLang scripts.
The docs: "PostForm issues a POST to the specified URL, with data's keys and values URL-encoded as the request body. The Content-Type header is set to application/x-www-form-urlencoded ."
Go can be also used to create web applications. Net/http is a library package used to build web applications. It has HandelFunc() function which routes the incoming request to its corresponding function. The ListenAndServe function is used to create a resource server which listens to the provided port.
You need to do two things: one is to wrap your mux with a middleware handler that pre-processes your requests and validates the IP. The other is get the real IP of the user, which is important if you are behind a firewall or load balancer (resulting in the address being always that of the LB), or if your user is behind a proxy.
As for wrapping your mux, it's pretty simple:
apiServer := &http.Server{
    Addr:    "0.0.0.0:8080",
    Handler: http.HandlerFunc( func(w http.ResponseWriter, req *http.Request) {
        // get the real IP of the user, see below
        addr := getRealAddr(req)
       // the actual vaildation - replace with whatever you want
       if (addr != "1.2.3.4") {
            http.Error(w, "Blocked", 401)
            return
        }
        // pass the request to the mux
        apiMux.ServeHTTP(w,req)
    }),
}
And I'm attaching the getRealAddr function which is from an actual project in which I did something like this:
func getRealAddr(r *http.Request)  string {
    remoteIP := ""
    // the default is the originating ip. but we try to find better options because this is almost
    // never the right IP
    if parts := strings.Split(r.RemoteAddr, ":"); len(parts) == 2 {
        remoteIP = parts[0]
    }
    // If we have a forwarded-for header, take the address from there
    if xff := strings.Trim(r.Header.Get("X-Forwarded-For"), ","); len(xff) > 0 {
        addrs := strings.Split(xff, ",")
        lastFwd := addrs[len(addrs)-1]
        if ip := net.ParseIP(lastFwd); ip != nil {
            remoteIP = ip.String()
        }
    // parse X-Real-Ip header
    } else if xri := r.Header.Get("X-Real-Ip"); len(xri) > 0 {
        if ip := net.ParseIP(xri); ip != nil {
            remoteIP = ip.String()
        }
    }
    return remoteIP
}
As for the filtering, it can be based on a set of ips, or CIDR ranges, it's up to you of course.
If you're interested, the above code is from an API building toolkit I wrote and used called Vertex, which has this built in: https://github.com/EverythingMe/vertex
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With