forked from Shiloh/githaven
116 lines
3.0 KiB
Go
116 lines
3.0 KiB
Go
|
// Copyright 2020 Lauris BH. All rights reserved.
|
||
|
// Use of this source code is governed by a MIT-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
package proxy
|
||
|
|
||
|
import (
|
||
|
"net"
|
||
|
)
|
||
|
|
||
|
// ForwardedHeadersOptions represents options for forwarded header middleware
|
||
|
type ForwardedHeadersOptions struct {
|
||
|
// ForwardLimit limits the number of entries in the headers that will be processed.
|
||
|
// The default value is 1. Set to 0 to disable the limit.
|
||
|
ForwardLimit int
|
||
|
// TrustingAllProxies option sets to trust all proxies.
|
||
|
TrustingAllProxies bool
|
||
|
// KnownProxies represents addresses of trusted proxies.
|
||
|
TrustedProxies []net.IP
|
||
|
// TrustedNetworks represents addresses of trusted networks.
|
||
|
TrustedNetworks []*net.IPNet
|
||
|
}
|
||
|
|
||
|
var defaultOptions = &ForwardedHeadersOptions{
|
||
|
ForwardLimit: 1,
|
||
|
TrustedProxies: []net.IP{
|
||
|
net.IPv4(127, 0, 0, 1),
|
||
|
},
|
||
|
}
|
||
|
|
||
|
// NewForwardedHeadersOptions creates new middleware options
|
||
|
func NewForwardedHeadersOptions() *ForwardedHeadersOptions {
|
||
|
return &ForwardedHeadersOptions{
|
||
|
ForwardLimit: defaultOptions.ForwardLimit,
|
||
|
TrustedProxies: defaultOptions.TrustedProxies,
|
||
|
TrustedNetworks: defaultOptions.TrustedNetworks,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// WithForwardLimit sets number of entries to be processed
|
||
|
func (opts *ForwardedHeadersOptions) WithForwardLimit(limit int) *ForwardedHeadersOptions {
|
||
|
opts.ForwardLimit = limit
|
||
|
return opts
|
||
|
}
|
||
|
|
||
|
// TrustAllProxies sets to trust all proxies
|
||
|
func (opts *ForwardedHeadersOptions) TrustAllProxies() *ForwardedHeadersOptions {
|
||
|
opts.TrustingAllProxies = true
|
||
|
return opts
|
||
|
}
|
||
|
|
||
|
// ClearTrustedProxies clears trusted proxy list
|
||
|
func (opts *ForwardedHeadersOptions) ClearTrustedProxies() *ForwardedHeadersOptions {
|
||
|
opts.TrustingAllProxies = false
|
||
|
opts.TrustedProxies = make([]net.IP, 0)
|
||
|
return opts
|
||
|
}
|
||
|
|
||
|
// AddTrustedProxy adds proxy IP to trusted proxy list
|
||
|
func (opts *ForwardedHeadersOptions) AddTrustedProxy(ip string) *ForwardedHeadersOptions {
|
||
|
// Special option to trust all proxies if IP address is set as wildcard
|
||
|
if ip == "*" {
|
||
|
opts.TrustingAllProxies = true
|
||
|
return opts
|
||
|
}
|
||
|
|
||
|
ipaddr := net.ParseIP(ip)
|
||
|
if ipaddr == nil {
|
||
|
return opts
|
||
|
}
|
||
|
|
||
|
opts.TrustedProxies = append(opts.TrustedProxies, ipaddr)
|
||
|
return opts
|
||
|
}
|
||
|
|
||
|
// ClearTrustedNetworks clears trusted network list
|
||
|
func (opts *ForwardedHeadersOptions) ClearTrustedNetworks() *ForwardedHeadersOptions {
|
||
|
opts.TrustedNetworks = make([]*net.IPNet, 0)
|
||
|
return opts
|
||
|
}
|
||
|
|
||
|
// AddTrustedNetwork adds network to trusted network list
|
||
|
func (opts *ForwardedHeadersOptions) AddTrustedNetwork(cidr string) *ForwardedHeadersOptions {
|
||
|
_, netmask, err := net.ParseCIDR(cidr)
|
||
|
if err != nil || netmask == nil {
|
||
|
return opts
|
||
|
}
|
||
|
|
||
|
opts.TrustedNetworks = append(opts.TrustedNetworks, netmask)
|
||
|
return opts
|
||
|
}
|
||
|
|
||
|
func (opts *ForwardedHeadersOptions) isTrustedProxy(ip net.IP) bool {
|
||
|
if opts.TrustingAllProxies {
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
if ip == nil {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
for _, tip := range opts.TrustedProxies {
|
||
|
if tip.Equal(ip) {
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for _, tnet := range opts.TrustedNetworks {
|
||
|
if tnet.Contains(ip) {
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false
|
||
|
}
|