mirror of
https://github.com/AdguardTeam/AdGuardDNS.git
synced 2025-02-20 11:23:36 +08:00
Sync v2.0.1
This commit is contained in:
parent
b6a98906a5
commit
328512e850
23
CHANGELOG.md
23
CHANGELOG.md
@ -11,6 +11,29 @@ The format is **not** based on [Keep a Changelog][kec], since the project
|
||||
|
||||
|
||||
|
||||
## AGDNS-1032 / Build 363
|
||||
|
||||
* The new optional field `static_content.*.allow_origin` has been added:
|
||||
|
||||
```yaml
|
||||
static_content:
|
||||
'/favicon.ico':
|
||||
allow_origin: '*'
|
||||
```
|
||||
|
||||
|
||||
|
||||
## AGDNS-898 / Build 359
|
||||
|
||||
* The new optional object `additional_metrics_info` has been added:
|
||||
|
||||
```yaml
|
||||
additional_metrics_info:
|
||||
test_key: 'test_value'
|
||||
```
|
||||
|
||||
|
||||
|
||||
## AGDNS-986 / Build 346
|
||||
|
||||
* The new object `upstream.healthcheck` now contains all healthcheck-related
|
||||
|
@ -156,6 +156,7 @@ web:
|
||||
# servers. Paths must not cross the ones used by the DNS-over-HTTPS server.
|
||||
static_content:
|
||||
'/favicon.ico':
|
||||
allow_origin: '*'
|
||||
content_type: 'image/x-icon'
|
||||
content: ''
|
||||
# If not defined, AdGuard DNS will respond with a 404 page to all such
|
||||
@ -326,3 +327,7 @@ server_groups:
|
||||
connectivity_check:
|
||||
probe_ipv4: '8.8.8.8:53'
|
||||
probe_ipv6: '[2001:4860:4860::8888]:53'
|
||||
|
||||
# Additional information to be exposed through metrics.
|
||||
additional_metrics_info:
|
||||
test_key: 'test_value'
|
||||
|
@ -24,6 +24,7 @@ configuration file with comments.
|
||||
* [DDR](#server_groups-*-ddr)
|
||||
* [Servers](#server_groups-*-servers-*)
|
||||
* [Connectivity Check](#connectivity-check)
|
||||
* [Additional Metrics Info](#additional_metrics_info)
|
||||
|
||||
[dist]: ../config.dist.yml
|
||||
[env]: environment.md
|
||||
@ -521,6 +522,8 @@ The `filters` object has the following properties:
|
||||
|
||||
**Example:** `5m`.
|
||||
|
||||
[env-blocked_services]: environment.md#BLOCKED_SERVICE_INDEX_URL
|
||||
|
||||
|
||||
|
||||
## <a href="#filtering_groups" id="filtering_groups" name="filtering_groups">Filtering Groups</a>
|
||||
@ -530,6 +533,7 @@ The items of the `filtering_groups` array have the following properties:
|
||||
* <a href="#fg-*-id" id="fg-*-id" name="fg-*-id">`id`</a>:
|
||||
The unique ID of this filtering group.
|
||||
|
||||
|
||||
**Example:** `default`.
|
||||
|
||||
* <a href="#fg-*-rule_lists" id="fg-*-rule_lists" name="fg-*-rule_lists">`rule_lists`</a>:
|
||||
@ -814,5 +818,30 @@ The `connectivity_check` object has the following properties:
|
||||
|
||||
**Example:** `[2001:4860:4860::8888]:53`.
|
||||
|
||||
[env-backend]: environment.md#BACKEND_ENDPOINT
|
||||
[env-blocked_services]: environment.md#BLOCKED_SERVICE_INDEX_URL
|
||||
|
||||
|
||||
## <a href="#additional_metrics_info" id="additional_metrics_info" name="additional_metrics_info">Additional Metrics Info</a>
|
||||
|
||||
The `additional_metrics_info` object is a map of strings with extra information
|
||||
which is exposed by `dns_app_additional_info` metric.
|
||||
|
||||
Map keys must match reqular expression `^[a-zA-Z_][a-zA-Z0-9_]*$`. See
|
||||
[Prometheus documentation on valid labels][prom-label].
|
||||
|
||||
**Property example:**
|
||||
|
||||
```yaml
|
||||
'additional_metrics_info':
|
||||
'info_key_1': 'info_value_1'
|
||||
'info_key_2': 'info_value_2'
|
||||
```
|
||||
|
||||
The Prometheus metrics key is `additional_info`. For example:
|
||||
|
||||
```none
|
||||
# HELP dns_app_additional_info A metric with a constant '1' value labeled by additional info provided in configuration
|
||||
# TYPE dns_app_additional_info gauge
|
||||
dns_app_additional_info{info_key_1="info_value_1",info_key_2="info_value_2"} 1
|
||||
```
|
||||
|
||||
[prom-label]: https://pkg.go.dev/github.com/prometheus/common/model#LabelNameRE
|
||||
|
2
go.mod
2
go.mod
@ -17,6 +17,7 @@ require (
|
||||
github.com/patrickmn/go-cache v2.1.1-0.20191004192108-46f407853014+incompatible
|
||||
github.com/prometheus/client_golang v1.13.0
|
||||
github.com/prometheus/client_model v0.2.0
|
||||
github.com/prometheus/common v0.37.0
|
||||
github.com/stretchr/testify v1.8.0
|
||||
go.etcd.io/bbolt v1.3.6
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e
|
||||
@ -48,7 +49,6 @@ require (
|
||||
github.com/onsi/ginkgo v1.16.5 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/common v0.37.0 // indirect
|
||||
github.com/prometheus/procfs v0.8.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
|
@ -14,7 +14,9 @@ import (
|
||||
// ServerGroup is a group of DNS servers all of which use the same filtering
|
||||
// settings.
|
||||
type ServerGroup struct {
|
||||
// TLS are the TLS settings for this server group, if any.
|
||||
// TLS are the TLS settings for this server group. If Servers contains at
|
||||
// least one server with a non-plain protocol (see [Protocol.IsPlain]), TLS
|
||||
// must not be nil.
|
||||
TLS *TLS
|
||||
|
||||
// DDR is the configuration for the server group's Discovery Of Designated
|
||||
|
30
internal/cmd/additional.go
Normal file
30
internal/cmd/additional.go
Normal file
@ -0,0 +1,30 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus/common/model"
|
||||
"golang.org/x/exp/maps"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
// additionalInfo is a extra info configuration.
|
||||
type additionalInfo map[string]string
|
||||
|
||||
// validateAdditionalInfo return an error is the section is invalid.
|
||||
func (c additionalInfo) validate() (err error) {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
keys := maps.Keys(c)
|
||||
slices.Sort(keys)
|
||||
|
||||
for _, k := range keys {
|
||||
if !model.LabelName(k).IsValid() {
|
||||
return fmt.Errorf("prometheus labels must match %s, got %q", model.LabelNameRE, k)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -64,6 +64,10 @@ func Main() {
|
||||
err = c.validate()
|
||||
fatalOnError(err)
|
||||
|
||||
// Additional Metrics
|
||||
|
||||
metrics.SetAdditionalInfo(c.AdditionalMetricsInfo)
|
||||
|
||||
// GeoIP Database
|
||||
|
||||
// We start GeoIP initialization early in a dedicated routine cause it
|
||||
|
@ -66,6 +66,9 @@ type configuration struct {
|
||||
// ConnectivityCheck is the connectivity check configuration.
|
||||
ConnectivityCheck *connCheckConfig `yaml:"connectivity_check"`
|
||||
|
||||
// AdditionalMetricsInfo is extra information, which is exposed by metrics.
|
||||
AdditionalMetricsInfo additionalInfo `yaml:"additional_metrics_info"`
|
||||
|
||||
// FilteringGroups are the predefined filtering configurations that are used
|
||||
// for different server groups.
|
||||
FilteringGroups filteringGroups `yaml:"filtering_groups"`
|
||||
@ -142,6 +145,9 @@ func (c *configuration) validate() (err error) {
|
||||
}, {
|
||||
validate: c.ConnectivityCheck.validate,
|
||||
name: "connectivity_check",
|
||||
}, {
|
||||
validate: c.AdditionalMetricsInfo.validate,
|
||||
name: "additional_metrics_info",
|
||||
}}
|
||||
|
||||
for _, v := range validators {
|
||||
|
@ -386,6 +386,9 @@ func (sc staticContent) validate() (err error) {
|
||||
|
||||
// staticFile is a single file in a static content mapping.
|
||||
type staticFile struct {
|
||||
// AllowOrigin is the value for the HTTP Access-Control-Allow-Origin header.
|
||||
AllowOrigin string `yaml:"allow_origin"`
|
||||
|
||||
// ContentType is the value for the HTTP Content-Type header.
|
||||
ContentType string `yaml:"content_type"`
|
||||
|
||||
@ -397,6 +400,7 @@ type staticFile struct {
|
||||
// assumed to be valid.
|
||||
func (f *staticFile) toInternal() (file *websvc.StaticFile, err error) {
|
||||
file = &websvc.StaticFile{
|
||||
AllowOrigin: f.AllowOrigin,
|
||||
ContentType: f.ContentType,
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,11 @@ func (p Protocol) ALPN() (alpn []string) {
|
||||
}
|
||||
}
|
||||
|
||||
// IsPlain returns true if the protocol is a plain DNS over TCP or UDP.
|
||||
func (p Protocol) IsPlain() (ok bool) {
|
||||
return p == ProtoDNSTCP || p == ProtoDNSUDP
|
||||
}
|
||||
|
||||
// IsStdEncrypted returns true if the protocol is one of the standard encrypted
|
||||
// DNS protocol as defined by an RFC.
|
||||
func (p Protocol) IsStdEncrypted() (ok bool) {
|
||||
|
@ -77,13 +77,11 @@ type ServerDNS struct {
|
||||
// type check
|
||||
var _ Server = (*ServerDNS)(nil)
|
||||
|
||||
// NewServerDNS creates a new ServerDNS instance.
|
||||
// NewServerDNS creates a new ServerDNS instance. conf.Proto must be either
|
||||
// [ProtoDNSTCP] or [ProtoDNSUDP].
|
||||
func NewServerDNS(conf ConfigDNS) (s *ServerDNS) {
|
||||
switch conf.Proto {
|
||||
case ProtoDNSTCP, ProtoDNSUDP:
|
||||
// Go on.
|
||||
default:
|
||||
panic(fmt.Errorf("invalid proto %v in NewServerDNS", conf.Proto))
|
||||
if !conf.Proto.IsPlain() {
|
||||
panic(fmt.Errorf("invalid proto %s in NewServerDNS", conf.Proto))
|
||||
}
|
||||
|
||||
return newServerDNS(conf)
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/AdguardTeam/AdGuardDNS/internal/errcoll"
|
||||
"github.com/AdguardTeam/AdGuardDNS/internal/optlog"
|
||||
"github.com/AdguardTeam/golibs/errors"
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// Device ID Extraction
|
||||
@ -163,3 +164,39 @@ func deviceIDFromContext(
|
||||
|
||||
return id, nil
|
||||
}
|
||||
|
||||
// dnsmasqCPEIDOption is the identifier of dnsmasq EDNS0 option
|
||||
// `EDNS0_OPTION_NOMCPEID`.
|
||||
//
|
||||
// See: https://github.com/PowerDNS/dnsmasq/blob/master/src/dns-protocol.h.
|
||||
const dnsmasqCPEIDOption uint16 = 65074
|
||||
|
||||
// deviceIDFromEDNS extracts the device ID from EDNS0 option of plain DNS
|
||||
// request. This method works with dnsmasq option `--add-cpe-id`, which adds
|
||||
// an identifying string to DNS queries through [dnsmasqCPEIDOption] option as
|
||||
// a non-standard support of Nominum servers.
|
||||
//
|
||||
// Requests of this kind could be emulated with `+ednsopt` option of `dig`
|
||||
// utility.
|
||||
// TODO(a.garipov): Add test documentation.
|
||||
func deviceIDFromEDNS(req *dns.Msg) (id agd.DeviceID, err error) {
|
||||
option := req.IsEdns0()
|
||||
if option == nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
for _, opt := range option.Option {
|
||||
if opt.Option() != dnsmasqCPEIDOption {
|
||||
continue
|
||||
}
|
||||
|
||||
o, ok := opt.(*dns.EDNS0_LOCAL)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
return agd.NewDeviceID(string(o.Data))
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
@ -6,8 +6,11 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardDNS/internal/agd"
|
||||
"github.com/AdguardTeam/AdGuardDNS/internal/dnsmsg"
|
||||
"github.com/AdguardTeam/AdGuardDNS/internal/dnsserver"
|
||||
"github.com/AdguardTeam/AdGuardDNS/internal/dnsserver/dnsservertest"
|
||||
"github.com/AdguardTeam/golibs/testutil"
|
||||
"github.com/miekg/dns"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@ -204,3 +207,66 @@ func TestService_Wrap_deviceIDHTTPS(t *testing.T) {
|
||||
assert.Equal(t, agd.DeviceID(want), deviceID)
|
||||
})
|
||||
}
|
||||
|
||||
func TestService_Wrap_deviceIDFromEDNS(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
opt dns.EDNS0
|
||||
wantDeviceID agd.DeviceID
|
||||
wantErrMsg string
|
||||
}{{
|
||||
name: "no_device_id",
|
||||
wantDeviceID: "",
|
||||
wantErrMsg: "",
|
||||
}, {
|
||||
name: "wrong_edns",
|
||||
opt: &dns.EDNS0_LOCAL{
|
||||
Code: dnsmasqCPEIDOption - 1,
|
||||
Data: []byte("devid"),
|
||||
},
|
||||
wantDeviceID: "",
|
||||
wantErrMsg: "",
|
||||
}, {
|
||||
name: "no_device_id",
|
||||
opt: &dns.EDNS0_LOCAL{
|
||||
Code: dnsmasqCPEIDOption,
|
||||
Data: []byte{},
|
||||
},
|
||||
wantDeviceID: "",
|
||||
wantErrMsg: `bad device id "": too short: got 0 bytes, min 1`,
|
||||
}, {
|
||||
name: "bad_device_id",
|
||||
opt: &dns.EDNS0_LOCAL{
|
||||
Code: dnsmasqCPEIDOption,
|
||||
Data: []byte("toolongdeviceid"),
|
||||
},
|
||||
wantDeviceID: "",
|
||||
wantErrMsg: `bad device id "toolongdeviceid": too long: got 15 bytes, max 8`,
|
||||
}, {
|
||||
name: "device_id",
|
||||
opt: &dns.EDNS0_LOCAL{
|
||||
Code: dnsmasqCPEIDOption,
|
||||
Data: []byte("devid"),
|
||||
},
|
||||
wantDeviceID: "devid",
|
||||
wantErrMsg: "",
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
msg := dnsservertest.NewReq("example.com.", dns.TypeA, dns.ClassINET)
|
||||
if tc.opt != nil {
|
||||
msg.SetEdns0(dnsmsg.DefaultEDNSUDPSize, true)
|
||||
extra := &dns.OPT{
|
||||
Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeOPT},
|
||||
Option: []dns.EDNS0{tc.opt},
|
||||
}
|
||||
msg.Extra = append(msg.Extra, extra)
|
||||
}
|
||||
|
||||
deviceID, err := deviceIDFromEDNS(msg)
|
||||
assert.Equal(t, tc.wantDeviceID, deviceID)
|
||||
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ func (mw *initMw) newRequestInfo(
|
||||
}
|
||||
|
||||
// Add the profile information, if any.
|
||||
err = mw.addProfile(ctx, ri)
|
||||
err = mw.addProfile(ctx, ri, req)
|
||||
if err != nil {
|
||||
// Don't wrap the error, because it's informative enough as is.
|
||||
return nil, err
|
||||
@ -245,15 +245,23 @@ func (mw *initMw) locationData(ctx context.Context, ip netip.Addr, typ string) (
|
||||
|
||||
// addProfile adds profile and device information, if any, to the request
|
||||
// information.
|
||||
func (mw *initMw) addProfile(ctx context.Context, ri *agd.RequestInfo) (err error) {
|
||||
func (mw *initMw) addProfile(ctx context.Context, ri *agd.RequestInfo, req *dns.Msg) (err error) {
|
||||
defer func() { err = errors.Annotate(err, "getting profile from req: %w") }()
|
||||
|
||||
var id agd.DeviceID
|
||||
if tlsConf := mw.srvGrp.TLS; tlsConf != nil {
|
||||
id, err = deviceIDFromContext(ctx, mw.srv.Protocol, tlsConf.DeviceIDWildcards)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if p := mw.srv.Protocol; p.IsStdEncrypted() {
|
||||
// Assume that mw.srvGrp.TLS is non-nil if p.IsStdEncrypted() is true.
|
||||
wildcards := mw.srvGrp.TLS.DeviceIDWildcards
|
||||
id, err = deviceIDFromContext(ctx, mw.srv.Protocol, wildcards)
|
||||
} else if p.IsPlain() {
|
||||
id, err = deviceIDFromEDNS(req)
|
||||
} else {
|
||||
// No DeviceID for DNSCrypt yet.
|
||||
return nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
optlog.Debug2("init mw: got device id %q and ip %s", id, ri.RemoteIP)
|
||||
@ -300,7 +308,7 @@ func (mw *initMw) profile(
|
||||
optlog.Debug1("init mw: not matching by ip for server %s", mw.srv.Name)
|
||||
|
||||
return nil, nil, "", agd.ProfileNotFoundError{}
|
||||
} else if p != agd.ProtoDNSUDP && p != agd.ProtoDNSTCP {
|
||||
} else if !p.IsPlain() {
|
||||
optlog.Debug1("init mw: not matching by ip for proto %v", p)
|
||||
|
||||
return nil, nil, "", agd.ProfileNotFoundError{}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package filter
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
@ -290,28 +291,11 @@ func (hs *HashStorage) refresh(ctx context.Context, acceptStale bool) (err error
|
||||
return hs.refr.refresh(ctx, acceptStale)
|
||||
}
|
||||
|
||||
// splitHosts splits a text made of hostnames, empty strings, and comments and
|
||||
// returns only the strings containing hostnames.
|
||||
//
|
||||
// TODO(a.garipov): Consider additional validation to make sure that it
|
||||
// actually is a list of hosts and NOT a list of filtering rules.
|
||||
func splitHosts(text string) (hosts []string) {
|
||||
hosts = strings.Split(text, "\n")
|
||||
hosts = stringutil.FilterOut(hosts, func(s string) (ok bool) {
|
||||
return len(s) == 0 || s[0] == '#'
|
||||
})
|
||||
|
||||
return hosts
|
||||
}
|
||||
|
||||
// resetHosts resets the hosts in the index. err is always nil, as it is only
|
||||
// there for compatibility with refreshFromFileOrURL.
|
||||
// resetHosts resets the hosts in the index.
|
||||
func (hs *HashStorage) resetHosts(hostsStr string) (err error) {
|
||||
hs.mu.Lock()
|
||||
defer hs.mu.Unlock()
|
||||
|
||||
hosts := splitHosts(hostsStr)
|
||||
|
||||
// Delete all elements without allocating a new map to safe space and
|
||||
// performance.
|
||||
//
|
||||
@ -320,17 +304,31 @@ func (hs *HashStorage) resetHosts(hostsStr string) (err error) {
|
||||
delete(hs.hashSuffixes, hp)
|
||||
}
|
||||
|
||||
for _, h := range hosts {
|
||||
sum := sha256.Sum256([]byte(h))
|
||||
var n int
|
||||
s := bufio.NewScanner(strings.NewReader(hostsStr))
|
||||
for s.Scan() {
|
||||
host := s.Text()
|
||||
if len(host) == 0 || host[0] == '#' {
|
||||
continue
|
||||
}
|
||||
|
||||
sum := sha256.Sum256([]byte(host))
|
||||
hp := hashPrefix{sum[0], sum[1]}
|
||||
|
||||
// TODO(a.garipov): Convert to array directly when proposal
|
||||
// golang/go#46505 is implemented in Go 1.20.
|
||||
suf := *(*hashSuffix)(sum[hashPrefixLen:])
|
||||
hs.hashSuffixes[hp] = append(hs.hashSuffixes[hp], suf)
|
||||
|
||||
n++
|
||||
}
|
||||
|
||||
log.Info("filter %s: reset %d hosts", hs.id(), len(hosts))
|
||||
err = s.Err()
|
||||
if err != nil {
|
||||
return fmt.Errorf("scanning hosts: %w", err)
|
||||
}
|
||||
|
||||
log.Info("filter %s: reset %d hosts", hs.id(), n)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -50,3 +50,42 @@ func BenchmarkHashStorage_Hashes(b *testing.B) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkHashStorage_resetHosts(b *testing.B) {
|
||||
const N = 1_000
|
||||
|
||||
var hosts []string
|
||||
for i := 0; i < N; i++ {
|
||||
hosts = append(hosts, fmt.Sprintf("%d.porn.example.com", i))
|
||||
}
|
||||
|
||||
// Don't use a constructor, since we don't need the whole contents of the
|
||||
// storage.
|
||||
//
|
||||
// TODO(a.garipov): Think of a better way to do this.
|
||||
hs := &HashStorage{
|
||||
mu: &sync.RWMutex{},
|
||||
hashSuffixes: map[hashPrefix][]hashSuffix{},
|
||||
refr: &refreshableFilter{id: "test_filter"},
|
||||
}
|
||||
|
||||
// Reset them once to fill the initial map.
|
||||
err := hs.resetHosts(strings.Join(hosts, "\n"))
|
||||
require.NoError(b, err)
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
err = hs.resetHosts(strings.Join(hosts, "\n"))
|
||||
}
|
||||
|
||||
require.NoError(b, err)
|
||||
|
||||
// Most recent result, on a ThinkPad X13 with a Ryzen Pro 7 CPU:
|
||||
//
|
||||
// goos: linux
|
||||
// goarch: amd64
|
||||
// pkg: github.com/AdguardTeam/AdGuardDNS/internal/filter
|
||||
// cpu: AMD Ryzen 7 PRO 4750U with Radeon Graphics
|
||||
// BenchmarkHashStorage_resetHosts-16 1404 829505 ns/op 58289 B/op 1011 allocs/op
|
||||
}
|
||||
|
@ -392,9 +392,10 @@ func BenchmarkStorage_NewDefaultStorage(b *testing.B) {
|
||||
assert.NotNil(b, defaultStorageSink)
|
||||
assert.NoError(b, errSink)
|
||||
|
||||
// Recent result on MBP 15
|
||||
// goos: darwin
|
||||
// goarch: amd64
|
||||
// cpu: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
|
||||
// BenchmarkStorage_NewDefaultStorage/success-12 3238 344513 ns/op 198096 B/op 952 allocs/op
|
||||
// Recent result on MBP 15:
|
||||
//
|
||||
// goos: darwin
|
||||
// goarch: amd64
|
||||
// cpu: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
|
||||
// BenchmarkStorage_NewDefaultStorage/success-12 3238 344513 ns/op 198096 B/op 952 allocs/op
|
||||
}
|
||||
|
@ -184,9 +184,10 @@ func BenchmarkNewFile(b *testing.B) {
|
||||
assert.NotNil(b, fileSink)
|
||||
assert.NoError(b, errSink)
|
||||
|
||||
// Recent result on MBP 15
|
||||
// goos: darwin
|
||||
// goarch: amd64
|
||||
// cpu: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
|
||||
// BenchmarkNewFile-12 2192 532262 ns/op 180929 B/op 5980 allocs/op
|
||||
// Recent result on MBP 15:
|
||||
//
|
||||
// goos: darwin
|
||||
// goarch: amd64
|
||||
// cpu: Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
|
||||
// BenchmarkNewFile-12 2192 532262 ns/op 180929 B/op 5980 allocs/op
|
||||
}
|
||||
|
@ -69,3 +69,24 @@ func BoolString(cond bool) (s string) {
|
||||
|
||||
return "0"
|
||||
}
|
||||
|
||||
// SetAdditionalInfo adds a gauge with extra info labels. If info is nil,
|
||||
// SetAdditionalInfo does nothing.
|
||||
func SetAdditionalInfo(info map[string]string) {
|
||||
if info == nil {
|
||||
return
|
||||
}
|
||||
|
||||
gauge := promauto.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "additional_info",
|
||||
Namespace: namespace,
|
||||
Subsystem: subsystemApplication,
|
||||
Help: `A metric with a constant '1' value labeled by additional ` +
|
||||
`info provided in configuration`,
|
||||
ConstLabels: info,
|
||||
},
|
||||
)
|
||||
|
||||
gauge.Set(1)
|
||||
}
|
||||
|
@ -114,9 +114,9 @@ func BenchmarkFileSystem_Write_file(b *testing.B) {
|
||||
|
||||
// Most recent result, on a ThinkPad X13 with a Ryzen Pro 7 CPU:
|
||||
//
|
||||
// goos: linux
|
||||
// goarch: amd64
|
||||
// pkg: github.com/AdguardTeam/AdGuardDNS/internal/querylog
|
||||
// cpu: AMD Ryzen 7 PRO 4750U with Radeon Graphics
|
||||
// BenchmarkFileSystem_Write_file-16 244162 5000 ns/op 200 B/op 3 allocs/op
|
||||
// goos: linux
|
||||
// goarch: amd64
|
||||
// pkg: github.com/AdguardTeam/AdGuardDNS/internal/querylog
|
||||
// cpu: AMD Ryzen 7 PRO 4750U with Radeon Graphics
|
||||
// BenchmarkFileSystem_Write_file-16 244162 5000 ns/op 200 B/op 3 allocs/op
|
||||
}
|
||||
|
@ -10,10 +10,11 @@ require (
|
||||
github.com/kyoh86/looppointer v0.1.8-0.20220224024524-f953a93c424a
|
||||
github.com/securego/gosec/v2 v2.13.1
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616
|
||||
golang.org/x/tools v0.1.12
|
||||
golang.org/x/tools v0.1.13-0.20220803210227-8b9a1fbdf5c3
|
||||
golang.org/x/vuln v0.0.0-20220902211423-27dd78d2ca39
|
||||
honnef.co/go/tools v0.3.3
|
||||
mvdan.cc/gofumpt v0.3.1
|
||||
mvdan.cc/unparam v0.0.0-20220706161116-678bad134442
|
||||
mvdan.cc/unparam v0.0.0-20220831102321-2fc90a84c7ec
|
||||
)
|
||||
|
||||
require (
|
||||
@ -21,13 +22,14 @@ require (
|
||||
github.com/client9/misspell v0.3.4 // indirect
|
||||
github.com/google/go-cmp v0.5.8 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gookit/color v1.5.1 // indirect
|
||||
github.com/gookit/color v1.5.2 // indirect
|
||||
github.com/kyoh86/nolint v0.0.1 // indirect
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20220722155223-a9213eeb770e // indirect
|
||||
golang.org/x/exp v0.0.0-20220827204233-334a2380cb91 // indirect
|
||||
golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect
|
||||
golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 // indirect
|
||||
golang.org/x/sys v0.0.0-20220906135438-9e1f76180b77 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
@ -2,19 +2,22 @@ github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0
|
||||
github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/frankban/quicktest v1.14.2 h1:SPb1KFFmM+ybpEjPUhCCkZOM5xlovT5UbrMvWnXyBns=
|
||||
github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo=
|
||||
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
|
||||
github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo=
|
||||
github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA=
|
||||
github.com/google/go-cmdtest v0.4.0 h1:ToXh6W5spLp3npJV92tk6d5hIpUPYEzHLkD+rncbyhI=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gookit/color v1.5.1 h1:Vjg2VEcdHpwq+oY63s/ksHrgJYCTo0bwWvmmYWdE9fQ=
|
||||
github.com/gookit/color v1.5.1/go.mod h1:wZFzea4X8qN6vHOSP2apMb4/+w/orMznEzYsIHPaqKM=
|
||||
github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI=
|
||||
github.com/gookit/color v1.5.2/go.mod h1:w8h4bGiHeeBpvQVePTutdbERIUf3oJE5lZ8HM0UgXyg=
|
||||
github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 h1:PVRE9d4AQKmbelZ7emNig1+NT27DUmKZn5qXxfio54U=
|
||||
github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0=
|
||||
github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7c=
|
||||
@ -36,9 +39,11 @@ github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XF
|
||||
github.com/securego/gosec/v2 v2.13.1 h1:7mU32qn2dyC81MH9L2kefnQyRMUarfDER3iQyMHcjYM=
|
||||
github.com/securego/gosec/v2 v2.13.1/go.mod h1:EO1sImBMBWFjOTFzMWfTRrZW6M15gm60ljzrmy/wtHo=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
@ -48,8 +53,10 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/exp/typeparams v0.0.0-20220722155223-a9213eeb770e h1:7Xs2YCOpMlNqSQSmrrnhlzBXIE/bpMecZplbLePTJvE=
|
||||
golang.org/x/exp/typeparams v0.0.0-20220722155223-a9213eeb770e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||
golang.org/x/exp v0.0.0-20220827204233-334a2380cb91 h1:tnebWN09GYg9OLPss1KXj8txwZc6X6uMr6VFdcGNbHw=
|
||||
golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
|
||||
golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 h1:Ic/qN6TEifvObMGQy72k0n1LlJr7DjWWEi+MOsDOiSk=
|
||||
golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
@ -81,8 +88,8 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220224003255-dbe011f71a99/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 h1:Sx/u41w+OwrInGdEckYmEuU5gHoGSL4QbDz3S9s6j4U=
|
||||
golang.org/x/sys v0.0.0-20220818161305-2296e01440c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220906135438-9e1f76180b77 h1:C1tElbkWrsSkn3IRl1GCW/gETw1TywWIPgwZtXTZbYg=
|
||||
golang.org/x/sys v0.0.0-20220906135438-9e1f76180b77/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
@ -96,8 +103,10 @@ golang.org/x/tools v0.0.0-20201007032633-0806396f153e/go.mod h1:z6u4i615ZeAfBE4X
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.1.13-0.20220803210227-8b9a1fbdf5c3 h1:aE4T3aJwdCNz+s35ScSQYUzeGu7BOLDHZ1bBHVurqqY=
|
||||
golang.org/x/tools v0.1.13-0.20220803210227-8b9a1fbdf5c3/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/vuln v0.0.0-20220902211423-27dd78d2ca39 h1:501+NfNjDh4IT4HOzdeezTOFD7njtY49aXJN1oY3E1s=
|
||||
golang.org/x/vuln v0.0.0-20220902211423-27dd78d2ca39/go.mod h1:7tDfEDtOLlzHQRi4Yzfg5seVBSvouUIjyPzBx4q5CxQ=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@ -106,11 +115,12 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR
|
||||
gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA=
|
||||
honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw=
|
||||
mvdan.cc/gofumpt v0.3.1 h1:avhhrOmv0IuvQVK7fvwV91oFSGAk5/6Po8GXTzICeu8=
|
||||
mvdan.cc/gofumpt v0.3.1/go.mod h1:w3ymliuxvzVx8DAutBnVyDqYb1Niy/yCJt/lk821YCE=
|
||||
mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 h1:seuXWbRB1qPrS3NQnHmFKLJLtskWyueeIzmLXghMGgk=
|
||||
mvdan.cc/unparam v0.0.0-20220706161116-678bad134442/go.mod h1:F/Cxw/6mVrNKqrR2YjFf5CaW0Bw4RL8RfbEf4GRggJk=
|
||||
mvdan.cc/unparam v0.0.0-20220831102321-2fc90a84c7ec h1:uyA9l4gQQUHSm9zPgTzarWmsjIw7s7hAldLwVxLlu1Y=
|
||||
mvdan.cc/unparam v0.0.0-20220831102321-2fc90a84c7ec/go.mod h1:EAphbHIduKNGVweyBBwWQd24rSnLy4DsjlpxRFYE498=
|
||||
|
@ -10,9 +10,9 @@ import (
|
||||
_ "github.com/kisielk/errcheck"
|
||||
_ "github.com/kyoh86/looppointer"
|
||||
_ "github.com/securego/gosec/v2/cmd/gosec"
|
||||
_ "golang.org/x/lint/golint"
|
||||
_ "golang.org/x/tools/go/analysis/passes/nilness/cmd/nilness"
|
||||
_ "golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow"
|
||||
_ "golang.org/x/vuln/cmd/govulncheck"
|
||||
_ "honnef.co/go/tools/cmd/staticcheck"
|
||||
_ "mvdan.cc/gofumpt"
|
||||
_ "mvdan.cc/unparam"
|
||||
|
@ -140,6 +140,9 @@ func (sc StaticContent) serveHTTP(w http.ResponseWriter, r *http.Request) (serve
|
||||
return false
|
||||
}
|
||||
|
||||
if f.AllowOrigin != "" {
|
||||
w.Header().Set(agdhttp.HdrNameAccessControlAllowOrigin, f.ContentType)
|
||||
}
|
||||
w.Header().Set(agdhttp.HdrNameContentType, f.ContentType)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
|
||||
@ -153,6 +156,9 @@ func (sc StaticContent) serveHTTP(w http.ResponseWriter, r *http.Request) (serve
|
||||
|
||||
// StaticFile is a single file in a StaticFS.
|
||||
type StaticFile struct {
|
||||
// AllowOrigin is the value for the HTTP Access-Control-Allow-Origin header.
|
||||
AllowOrigin string
|
||||
|
||||
// ContentType is the value for the HTTP Content-Type header.
|
||||
ContentType string
|
||||
|
||||
|
@ -215,6 +215,8 @@ exit_on_output gofumpt --extra -e -l .
|
||||
|
||||
"$GO" vet ./... "$dnssrvmod"
|
||||
|
||||
govulncheck ./... "$dnssrvmod"
|
||||
|
||||
gocyclo --over 10 .
|
||||
|
||||
ineffassign ./... "$dnssrvmod"
|
||||
|
@ -30,22 +30,23 @@ readonly go
|
||||
# prevent the "cannot install cross-compiled binaries when GOBIN is set" error.
|
||||
env\
|
||||
GOARCH=""\
|
||||
GOOS=""\
|
||||
GOBIN="${PWD}/bin"\
|
||||
GOOS=""\
|
||||
GOWORK='off'\
|
||||
"$go" install\
|
||||
--modfile=./internal/tools/go.mod\
|
||||
$v_flags $x_flags\
|
||||
$v_flags\
|
||||
$x_flags\
|
||||
github.com/fzipp/gocyclo/cmd/gocyclo\
|
||||
github.com/golangci/misspell/cmd/misspell\
|
||||
github.com/gordonklaus/ineffassign\
|
||||
github.com/kisielk/errcheck\
|
||||
github.com/kyoh86/looppointer/cmd/looppointer\
|
||||
github.com/securego/gosec/v2/cmd/gosec\
|
||||
golang.org/x/lint/golint\
|
||||
golang.org/x/tools/go/analysis/passes/fieldalignment/cmd/fieldalignment\
|
||||
golang.org/x/tools/go/analysis/passes/nilness/cmd/nilness\
|
||||
golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow\
|
||||
golang.org/x/vuln/cmd/govulncheck\
|
||||
honnef.co/go/tools/cmd/staticcheck\
|
||||
mvdan.cc/gofumpt\
|
||||
mvdan.cc/unparam\
|
||||
|
Loading…
x
Reference in New Issue
Block a user