func (f *ipFilter) ToggleDefault(allowed bool) {
	f.mut.Lock()
	f.defaultAllowed = allowed
	f.mut.Unlock()
}
ToggleDefault alters the default setting
package server
import (
	"log"
	"net"
	"net/http"
	"os"
	"sync"
	"github.com/tomasen/realip"
)
type IPFilterOptions struct {
	AllowedIPs []string
	BlockedIPs []string
	BlockByDefault bool
	TrustProxy bool
	Logger interface {
		Printf(format string, v ...interface{})
	}
}
type ipFilter struct {
	opts IPFilterOptions
	mut            sync.RWMutex
	defaultAllowed bool
	ips            map[string]bool
	subnets        []*subnet
}
type subnet struct {
	str     string
	ipnet   *net.IPNet
	allowed bool
}
func newIPFilter(opts IPFilterOptions) *ipFilter {
	if opts.Logger == nil {
		flags := log.LstdFlags
		opts.Logger = log.New(os.Stdout, "", flags)
	}
	f := &ipFilter{
		opts:           opts,
		ips:            map[string]bool{},
		defaultAllowed: !opts.BlockByDefault,
	}
	for _, ip := range opts.BlockedIPs {
		f.BlockIP(ip)
	}
	for _, ip := range opts.AllowedIPs {
		f.AllowIP(ip)
	}
	return f
}
func (f *ipFilter) AllowIP(ip string) bool {
	return f.ToggleIP(ip, true)
}
func (f *ipFilter) BlockIP(ip string) bool {
	return f.ToggleIP(ip, false)
}
func (f *ipFilter) ToggleIP(str string, allowed bool) bool {
	if ip, net, err := net.ParseCIDR(str); err == nil {
		if n, total := net.Mask.Size(); n == total {
			f.mut.Lock()
			f.ips[ip.String()] = allowed
			f.mut.Unlock()
			return true
		}
		f.mut.Lock()
		found := false
		for _, subnet := range f.subnets {
			if subnet.str == str {
				found = true
				subnet.allowed = allowed
				break
			}
		}
		if !found {
			f.subnets = append(f.subnets, &subnet{
				str:     str,
				ipnet:   net,
				allowed: allowed,
			})
		}
		f.mut.Unlock()
		return true
	}
	if ip := net.ParseIP(str); ip != nil {
		f.mut.Lock()
		f.ips[ip.String()] = allowed
		f.mut.Unlock()
		return true
	}
	return false
}