Pull request: all: add string set
Merge in DNS/adguard-home from add-strset to master Squashed commit of the following: commit 2500df1805dee425eafd0503983ec631de02af0b Author: Ainar Garipov <A.Garipov@AdGuard.COM> Date: Tue Apr 20 15:09:59 2021 +0300 all: add string set
This commit is contained in:
parent
71030bafd8
commit
93638a1936
|
@ -15,9 +15,6 @@ import (
|
||||||
// implementation must be safe for concurrent use.
|
// implementation must be safe for concurrent use.
|
||||||
type HostGenFunc func() (host string)
|
type HostGenFunc func() (host string)
|
||||||
|
|
||||||
// unit is an alias for an existing map value.
|
|
||||||
type unit = struct{}
|
|
||||||
|
|
||||||
// SystemResolvers helps to work with local resolvers' addresses provided by OS.
|
// SystemResolvers helps to work with local resolvers' addresses provided by OS.
|
||||||
type SystemResolvers interface {
|
type SystemResolvers interface {
|
||||||
// Get returns the slice of local resolvers' addresses.
|
// Get returns the slice of local resolvers' addresses.
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/agherr"
|
"github.com/AdguardTeam/AdGuardHome/internal/agherr"
|
||||||
|
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// defaultHostGen is the default method of generating host for Refresh.
|
// defaultHostGen is the default method of generating host for Refresh.
|
||||||
|
@ -24,8 +25,8 @@ type systemResolvers struct {
|
||||||
resolver *net.Resolver
|
resolver *net.Resolver
|
||||||
hostGenFunc HostGenFunc
|
hostGenFunc HostGenFunc
|
||||||
|
|
||||||
// addrs is the map that contains cached local resolvers' addresses.
|
// addrs is the set that contains cached local resolvers' addresses.
|
||||||
addrs map[string]unit
|
addrs *aghstrings.Set
|
||||||
addrsLock sync.RWMutex
|
addrsLock sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +51,7 @@ func newSystemResolvers(refreshIvl time.Duration, hostGenFunc HostGenFunc) (sr S
|
||||||
PreferGo: true,
|
PreferGo: true,
|
||||||
},
|
},
|
||||||
hostGenFunc: hostGenFunc,
|
hostGenFunc: hostGenFunc,
|
||||||
addrs: make(map[string]unit),
|
addrs: aghstrings.NewSet(),
|
||||||
}
|
}
|
||||||
s.resolver.Dial = s.dialFunc
|
s.resolver.Dial = s.dialFunc
|
||||||
|
|
||||||
|
@ -75,7 +76,7 @@ func (sr *systemResolvers) dialFunc(_ context.Context, _, address string) (_ net
|
||||||
sr.addrsLock.Lock()
|
sr.addrsLock.Lock()
|
||||||
defer sr.addrsLock.Unlock()
|
defer sr.addrsLock.Unlock()
|
||||||
|
|
||||||
sr.addrs[host] = unit{}
|
sr.addrs.Add(host)
|
||||||
|
|
||||||
return nil, fakeDialErr
|
return nil, fakeDialErr
|
||||||
}
|
}
|
||||||
|
@ -84,13 +85,5 @@ func (sr *systemResolvers) Get() (rs []string) {
|
||||||
sr.addrsLock.RLock()
|
sr.addrsLock.RLock()
|
||||||
defer sr.addrsLock.RUnlock()
|
defer sr.addrsLock.RUnlock()
|
||||||
|
|
||||||
addrs := sr.addrs
|
return sr.addrs.Values()
|
||||||
rs = make([]string, len(addrs))
|
|
||||||
var i int
|
|
||||||
for addr := range addrs {
|
|
||||||
rs[i] = addr
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
|
|
||||||
return rs
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
||||||
|
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
|
||||||
"github.com/AdguardTeam/dnsproxy/upstream"
|
"github.com/AdguardTeam/dnsproxy/upstream"
|
||||||
"github.com/AdguardTeam/golibs/cache"
|
"github.com/AdguardTeam/golibs/cache"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
|
@ -477,10 +478,10 @@ func (d *DNSFilter) processRewrites(host string, qtype uint16) (res Result) {
|
||||||
res.Reason = Rewritten
|
res.Reason = Rewritten
|
||||||
}
|
}
|
||||||
|
|
||||||
cnames := map[string]bool{}
|
cnames := aghstrings.NewSet()
|
||||||
origHost := host
|
origHost := host
|
||||||
for len(rr) != 0 && rr[0].Type == dns.TypeCNAME {
|
for len(rr) != 0 && rr[0].Type == dns.TypeCNAME {
|
||||||
log.Debug("Rewrite: CNAME for %s is %s", host, rr[0].Answer)
|
log.Debug("rewrite: CNAME for %s is %s", host, rr[0].Answer)
|
||||||
|
|
||||||
if host == rr[0].Answer { // "host == CNAME" is an exception
|
if host == rr[0].Answer { // "host == CNAME" is an exception
|
||||||
res.Reason = NotFilteredNotFound
|
res.Reason = NotFilteredNotFound
|
||||||
|
@ -489,12 +490,13 @@ func (d *DNSFilter) processRewrites(host string, qtype uint16) (res Result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
host = rr[0].Answer
|
host = rr[0].Answer
|
||||||
_, ok := cnames[host]
|
if cnames.Has(host) {
|
||||||
if ok {
|
log.Info("rewrite: breaking CNAME redirection loop: %s. Question: %s", host, origHost)
|
||||||
log.Info("Rewrite: breaking CNAME redirection loop: %s. Question: %s", host, origHost)
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
cnames[host] = false
|
|
||||||
|
cnames.Add(host)
|
||||||
res.CanonName = rr[0].Answer
|
res.CanonName = rr[0].Answer
|
||||||
rr = findRewrites(d.Rewrites, host)
|
rr = findRewrites(d.Rewrites, host)
|
||||||
}
|
}
|
||||||
|
@ -509,7 +511,7 @@ func (d *DNSFilter) processRewrites(host string, qtype uint16) (res Result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
res.IPList = append(res.IPList, r.IP)
|
res.IPList = append(res.IPList, r.IP)
|
||||||
log.Debug("Rewrite: A/AAAA for %s is %s", host, r.IP)
|
log.Debug("rewrite: A/AAAA for %s is %s", host, r.IP)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,11 @@ import (
|
||||||
type accessCtx struct {
|
type accessCtx struct {
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
|
|
||||||
allowedClients map[string]bool // IP addresses of whitelist clients
|
// allowedClients are the IP addresses of clients in the allowlist.
|
||||||
disallowedClients map[string]bool // IP addresses of clients that should be blocked
|
allowedClients *aghstrings.Set
|
||||||
|
|
||||||
|
// disallowedClients are the IP addresses of clients in the blocklist.
|
||||||
|
disallowedClients *aghstrings.Set
|
||||||
|
|
||||||
allowedClientsIPNet []net.IPNet // CIDRs of whitelist clients
|
allowedClientsIPNet []net.IPNet // CIDRs of whitelist clients
|
||||||
disallowedClientsIPNet []net.IPNet // CIDRs of clients that should be blocked
|
disallowedClientsIPNet []net.IPNet // CIDRs of clients that should be blocked
|
||||||
|
@ -26,15 +29,20 @@ type accessCtx struct {
|
||||||
blockedHostsEngine *urlfilter.DNSEngine // finds hosts that should be blocked
|
blockedHostsEngine *urlfilter.DNSEngine // finds hosts that should be blocked
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *accessCtx) Init(allowedClients, disallowedClients, blockedHosts []string) error {
|
func newAccessCtx(allowedClients, disallowedClients, blockedHosts []string) (a *accessCtx, err error) {
|
||||||
err := processIPCIDRArray(&a.allowedClients, &a.allowedClientsIPNet, allowedClients)
|
a = &accessCtx{
|
||||||
if err != nil {
|
allowedClients: aghstrings.NewSet(),
|
||||||
return err
|
disallowedClients: aghstrings.NewSet(),
|
||||||
}
|
}
|
||||||
|
|
||||||
err = processIPCIDRArray(&a.disallowedClients, &a.disallowedClientsIPNet, disallowedClients)
|
err = processIPCIDRArray(a.allowedClients, &a.allowedClientsIPNet, allowedClients)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, fmt.Errorf("processing allowed clients: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = processIPCIDRArray(a.disallowedClients, &a.disallowedClientsIPNet, disallowedClients)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("processing disallowed clients: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
b := &strings.Builder{}
|
b := &strings.Builder{}
|
||||||
|
@ -51,21 +59,20 @@ func (a *accessCtx) Init(allowedClients, disallowedClients, blockedHosts []strin
|
||||||
listArray = append(listArray, list)
|
listArray = append(listArray, list)
|
||||||
rulesStorage, err := filterlist.NewRuleStorage(listArray)
|
rulesStorage, err := filterlist.NewRuleStorage(listArray)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("filterlist.NewRuleStorage(): %w", err)
|
return nil, fmt.Errorf("filterlist.NewRuleStorage(): %w", err)
|
||||||
}
|
}
|
||||||
a.blockedHostsEngine = urlfilter.NewDNSEngine(rulesStorage)
|
a.blockedHostsEngine = urlfilter.NewDNSEngine(rulesStorage)
|
||||||
|
|
||||||
return nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split array of IP or CIDR into 2 containers for fast search
|
// Split array of IP or CIDR into 2 containers for fast search
|
||||||
func processIPCIDRArray(dst *map[string]bool, dstIPNet *[]net.IPNet, src []string) error {
|
func processIPCIDRArray(dst *aghstrings.Set, dstIPNet *[]net.IPNet, src []string) error {
|
||||||
*dst = make(map[string]bool)
|
|
||||||
|
|
||||||
for _, s := range src {
|
for _, s := range src {
|
||||||
ip := net.ParseIP(s)
|
ip := net.ParseIP(s)
|
||||||
if ip != nil {
|
if ip != nil {
|
||||||
(*dst)[s] = true
|
dst.Add(s)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +80,7 @@ func processIPCIDRArray(dst *map[string]bool, dstIPNet *[]net.IPNet, src []strin
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
*dstIPNet = append(*dstIPNet, *ipnet)
|
*dstIPNet = append(*dstIPNet, *ipnet)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,9 +97,8 @@ func (a *accessCtx) IsBlockedIP(ip net.IP) (bool, string) {
|
||||||
a.lock.Lock()
|
a.lock.Lock()
|
||||||
defer a.lock.Unlock()
|
defer a.lock.Unlock()
|
||||||
|
|
||||||
if len(a.allowedClients) != 0 || len(a.allowedClientsIPNet) != 0 {
|
if a.allowedClients.Len() != 0 || len(a.allowedClientsIPNet) != 0 {
|
||||||
_, ok := a.allowedClients[ipStr]
|
if a.allowedClients.Has(ipStr) {
|
||||||
if ok {
|
|
||||||
return false, ""
|
return false, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,8 +113,7 @@ func (a *accessCtx) IsBlockedIP(ip net.IP) (bool, string) {
|
||||||
return true, ""
|
return true, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
_, ok := a.disallowedClients[ipStr]
|
if a.disallowedClients.Has(ipStr) {
|
||||||
if ok {
|
|
||||||
return true, ipStr
|
return true, ipStr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,10 +192,11 @@ func (s *Server) handleAccessSet(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
a := &accessCtx{}
|
var a *accessCtx
|
||||||
err = a.Init(j.AllowedClients, j.DisallowedClients, j.BlockedHosts)
|
a, err = newAccessCtx(j.AllowedClients, j.DisallowedClients, j.BlockedHosts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
httpError(r, w, http.StatusBadRequest, "access.Init: %s", err)
|
httpError(r, w, http.StatusBadRequest, "creating access ctx: %s", err)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,6 @@ func TestIsBlockedIP(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run(prefix+tc.name, func(t *testing.T) {
|
t.Run(prefix+tc.name, func(t *testing.T) {
|
||||||
aCtx := &accessCtx{}
|
|
||||||
allowedRules := rules
|
allowedRules := rules
|
||||||
var disallowedRules []string
|
var disallowedRules []string
|
||||||
|
|
||||||
|
@ -90,7 +89,8 @@ func TestIsBlockedIP(t *testing.T) {
|
||||||
allowedRules, disallowedRules = disallowedRules, allowedRules
|
allowedRules, disallowedRules = disallowedRules, allowedRules
|
||||||
}
|
}
|
||||||
|
|
||||||
require.Nil(t, aCtx.Init(allowedRules, disallowedRules, nil))
|
aCtx, err := newAccessCtx(allowedRules, disallowedRules, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
disallowed, rule := aCtx.IsBlockedIP(tc.ip)
|
disallowed, rule := aCtx.IsBlockedIP(tc.ip)
|
||||||
assert.Equal(t, tc.wantDis, disallowed)
|
assert.Equal(t, tc.wantDis, disallowed)
|
||||||
|
@ -100,12 +100,12 @@ func TestIsBlockedIP(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIsBlockedDomain(t *testing.T) {
|
func TestIsBlockedDomain(t *testing.T) {
|
||||||
aCtx := &accessCtx{}
|
aCtx, err := newAccessCtx(nil, nil, []string{
|
||||||
require.Nil(t, aCtx.Init(nil, nil, []string{
|
|
||||||
"host1",
|
"host1",
|
||||||
"*.host.com",
|
"*.host.com",
|
||||||
"||host3.com^",
|
"||host3.com^",
|
||||||
}))
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
|
|
|
@ -340,19 +340,6 @@ func (s *Server) collectDNSIPAddrs() (addrs []string, err error) {
|
||||||
return addrs[:i], nil
|
return addrs[:i], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// unit is used to show the presence of a value in a set.
|
|
||||||
type unit = struct{}
|
|
||||||
|
|
||||||
// sliceToSet converts a slice of strings into a string set.
|
|
||||||
func sliceToSet(strs []string) (set map[string]unit) {
|
|
||||||
set = make(map[string]unit, len(strs))
|
|
||||||
for _, s := range strs {
|
|
||||||
set[s] = unit{}
|
|
||||||
}
|
|
||||||
|
|
||||||
return set
|
|
||||||
}
|
|
||||||
|
|
||||||
// setupResolvers initializes the resolvers for local addresses. For internal
|
// setupResolvers initializes the resolvers for local addresses. For internal
|
||||||
// use only.
|
// use only.
|
||||||
func (s *Server) setupResolvers(localAddrs []string) (err error) {
|
func (s *Server) setupResolvers(localAddrs []string) (err error) {
|
||||||
|
@ -377,16 +364,14 @@ func (s *Server) setupResolvers(localAddrs []string) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ourAddrsSet := sliceToSet(ourAddrs)
|
ourAddrsSet := aghstrings.NewSet(ourAddrs...)
|
||||||
|
|
||||||
// TODO(e.burkov): The approach of subtracting sets of strings is not
|
// TODO(e.burkov): The approach of subtracting sets of strings is not
|
||||||
// really applicable here since in case of listening on all network
|
// really applicable here since in case of listening on all network
|
||||||
// interfaces we should check the whole interface's network to cut off
|
// interfaces we should check the whole interface's network to cut off
|
||||||
// all the loopback addresses as well.
|
// all the loopback addresses as well.
|
||||||
localAddrs = aghstrings.FilterOut(localAddrs, func(s string) (ok bool) {
|
localAddrs = aghstrings.FilterOut(localAddrs, func(s string) (ok bool) {
|
||||||
_, ok = ourAddrsSet[s]
|
return ourAddrsSet.Has(s)
|
||||||
|
|
||||||
return ok
|
|
||||||
})
|
})
|
||||||
|
|
||||||
var upsConfig proxy.UpstreamConfig
|
var upsConfig proxy.UpstreamConfig
|
||||||
|
@ -464,10 +449,7 @@ func (s *Server) Prepare(config *ServerConfig) error {
|
||||||
// --
|
// --
|
||||||
s.prepareIntlProxy()
|
s.prepareIntlProxy()
|
||||||
|
|
||||||
// Initialize DNS access module
|
s.access, err = newAccessCtx(s.conf.AllowedClients, s.conf.DisallowedClients, s.conf.BlockedHosts)
|
||||||
// --
|
|
||||||
s.access = &accessCtx{}
|
|
||||||
err = s.access.Init(s.conf.AllowedClients, s.conf.DisallowedClients, s.conf.BlockedHosts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ type clientsContainer struct {
|
||||||
ipToRC map[string]*RuntimeClient // IP -> runtime client
|
ipToRC map[string]*RuntimeClient // IP -> runtime client
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
|
|
||||||
allTags map[string]bool
|
allTags *aghstrings.Set
|
||||||
|
|
||||||
// dhcpServer is used for looking up clients IP addresses by MAC addresses
|
// dhcpServer is used for looking up clients IP addresses by MAC addresses
|
||||||
dhcpServer *dhcpd.Server
|
dhcpServer *dhcpd.Server
|
||||||
|
@ -111,10 +111,7 @@ func (clients *clientsContainer) Init(
|
||||||
clients.idIndex = make(map[string]*Client)
|
clients.idIndex = make(map[string]*Client)
|
||||||
clients.ipToRC = make(map[string]*RuntimeClient)
|
clients.ipToRC = make(map[string]*RuntimeClient)
|
||||||
|
|
||||||
clients.allTags = make(map[string]bool)
|
clients.allTags = aghstrings.NewSet(clientTags...)
|
||||||
for _, t := range clientTags {
|
|
||||||
clients.allTags[t] = false
|
|
||||||
}
|
|
||||||
|
|
||||||
clients.dhcpServer = dhcpServer
|
clients.dhcpServer = dhcpServer
|
||||||
clients.etcHosts = etcHosts
|
clients.etcHosts = etcHosts
|
||||||
|
@ -163,9 +160,8 @@ type clientObject struct {
|
||||||
Upstreams []string `yaml:"upstreams"`
|
Upstreams []string `yaml:"upstreams"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (clients *clientsContainer) tagKnown(tag string) bool {
|
func (clients *clientsContainer) tagKnown(tag string) (ok bool) {
|
||||||
_, ok := clients.allTags[tag]
|
return clients.allTags.Has(tag)
|
||||||
return ok
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (clients *clientsContainer) addFromConfig(objects []clientObject) {
|
func (clients *clientsContainer) addFromConfig(objects []clientObject) {
|
||||||
|
|
|
@ -6,52 +6,46 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// --------------------
|
// TODO(a.garipov): Get rid of a global variable?
|
||||||
// internationalization
|
var allowedLanguages = aghstrings.NewSet(
|
||||||
// --------------------
|
"be",
|
||||||
var allowedLanguages = map[string]bool{
|
"bg",
|
||||||
"be": true,
|
"cs",
|
||||||
"bg": true,
|
"da",
|
||||||
"cs": true,
|
"de",
|
||||||
"da": true,
|
"en",
|
||||||
"de": true,
|
"es",
|
||||||
"en": true,
|
"fa",
|
||||||
"es": true,
|
"fr",
|
||||||
"fa": true,
|
"hr",
|
||||||
"fr": true,
|
"hu",
|
||||||
"hr": true,
|
"id",
|
||||||
"hu": true,
|
"it",
|
||||||
"id": true,
|
"ja",
|
||||||
"it": true,
|
"ko",
|
||||||
"ja": true,
|
"nl",
|
||||||
"ko": true,
|
"no",
|
||||||
"nl": true,
|
"pl",
|
||||||
"no": true,
|
"pt-br",
|
||||||
"pl": true,
|
"pt-pt",
|
||||||
"pt-br": true,
|
"ro",
|
||||||
"pt-pt": true,
|
"ru",
|
||||||
"ro": true,
|
"si-lk",
|
||||||
"ru": true,
|
"sk",
|
||||||
"si-lk": true,
|
"sl",
|
||||||
"sk": true,
|
"sr-cs",
|
||||||
"sl": true,
|
"sv",
|
||||||
"sr-cs": true,
|
"th",
|
||||||
"sv": true,
|
"tr",
|
||||||
"th": true,
|
"vi",
|
||||||
"tr": true,
|
"zh-cn",
|
||||||
"vi": true,
|
"zh-hk",
|
||||||
"zh-cn": true,
|
"zh-tw",
|
||||||
"zh-hk": true,
|
)
|
||||||
"zh-tw": true,
|
|
||||||
}
|
|
||||||
|
|
||||||
func isLanguageAllowed(language string) bool {
|
|
||||||
l := strings.ToLower(language)
|
|
||||||
return allowedLanguages[l]
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleI18nCurrentLanguage(w http.ResponseWriter, r *http.Request) {
|
func handleI18nCurrentLanguage(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "text/plain")
|
w.Header().Set("Content-Type", "text/plain")
|
||||||
|
@ -80,12 +74,15 @@ func handleI18nChangeLanguage(w http.ResponseWriter, r *http.Request) {
|
||||||
msg := "empty language specified"
|
msg := "empty language specified"
|
||||||
log.Println(msg)
|
log.Println(msg)
|
||||||
http.Error(w, msg, http.StatusBadRequest)
|
http.Error(w, msg, http.StatusBadRequest)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !isLanguageAllowed(language) {
|
|
||||||
|
if !allowedLanguages.Has(language) {
|
||||||
msg := fmt.Sprintf("unknown language specified: %s", language)
|
msg := fmt.Sprintf("unknown language specified: %s", language)
|
||||||
log.Println(msg)
|
log.Println(msg)
|
||||||
http.Error(w, msg, http.StatusBadRequest)
|
http.Error(w, msg, http.StatusBadRequest)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/aghtest"
|
"github.com/AdguardTeam/AdGuardHome/internal/aghtest"
|
||||||
"github.com/AdguardTeam/dnsproxy/upstream"
|
"github.com/AdguardTeam/dnsproxy/upstream"
|
||||||
"github.com/AdguardTeam/golibs/cache"
|
"github.com/AdguardTeam/golibs/cache"
|
||||||
|
@ -82,7 +83,7 @@ func TestRDNS_Begin(t *testing.T) {
|
||||||
list: map[string]*Client{},
|
list: map[string]*Client{},
|
||||||
idIndex: tc.cliIDIndex,
|
idIndex: tc.cliIDIndex,
|
||||||
ipToRC: map[string]*RuntimeClient{},
|
ipToRC: map[string]*RuntimeClient{},
|
||||||
allTags: map[string]bool{},
|
allTags: aghstrings.NewSet(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ipCache.Clear()
|
ipCache.Clear()
|
||||||
|
@ -172,7 +173,7 @@ func TestRDNS_WorkerLoop(t *testing.T) {
|
||||||
list: map[string]*Client{},
|
list: map[string]*Client{},
|
||||||
idIndex: map[string]*Client{},
|
idIndex: map[string]*Client{},
|
||||||
ipToRC: map[string]*RuntimeClient{},
|
ipToRC: map[string]*RuntimeClient{},
|
||||||
allTags: map[string]bool{},
|
allTags: aghstrings.NewSet(),
|
||||||
}
|
}
|
||||||
ch := make(chan net.IP)
|
ch := make(chan net.IP)
|
||||||
rdns := &RDNS{
|
rdns := &RDNS{
|
||||||
|
|
Loading…
Reference in New Issue