next: upd more

This commit is contained in:
Ainar Garipov 2024-11-11 21:08:51 +03:00
parent 05eec75222
commit 0c64e6cfc6
7 changed files with 74 additions and 76 deletions

3
go.mod
View file

@ -4,8 +4,7 @@ go 1.23.3
require ( require (
github.com/AdguardTeam/dnsproxy v0.73.3 github.com/AdguardTeam/dnsproxy v0.73.3
// TODO(a.garipov): !! Update to tag! github.com/AdguardTeam/golibs v0.30.3
github.com/AdguardTeam/golibs v0.30.3-0.20241108140605-ec84c9f86663
github.com/AdguardTeam/urlfilter v0.20.0 github.com/AdguardTeam/urlfilter v0.20.0
github.com/NYTimes/gziphandler v1.1.1 github.com/NYTimes/gziphandler v1.1.1
github.com/ameshkov/dnscrypt/v2 v2.3.0 github.com/ameshkov/dnscrypt/v2 v2.3.0

4
go.sum
View file

@ -1,7 +1,7 @@
github.com/AdguardTeam/dnsproxy v0.73.3 h1:aacr6Wu0ed94DDD+gSB6EwF8nvyq0+DAc7oFOgtgUpA= github.com/AdguardTeam/dnsproxy v0.73.3 h1:aacr6Wu0ed94DDD+gSB6EwF8nvyq0+DAc7oFOgtgUpA=
github.com/AdguardTeam/dnsproxy v0.73.3/go.mod h1:18ssqhDgOCiVIwYmmVuXVM05wSwrzkO2yjKhVRWJX/g= github.com/AdguardTeam/dnsproxy v0.73.3/go.mod h1:18ssqhDgOCiVIwYmmVuXVM05wSwrzkO2yjKhVRWJX/g=
github.com/AdguardTeam/golibs v0.30.3-0.20241108140605-ec84c9f86663 h1:2uhyDq3f4BV48TjXDS0itBU2iwyuWKk1HGLujIJmbd0= github.com/AdguardTeam/golibs v0.30.3 h1:pRxLjMCJ1cZccjZWMMuKxzQQGEpFbmtyj4Tg7nk5rY0=
github.com/AdguardTeam/golibs v0.30.3-0.20241108140605-ec84c9f86663/go.mod h1:Ir9dlHfb8nRQsG3Qgo1zoGL+k1qMbcBtb8tcnsvzdAE= github.com/AdguardTeam/golibs v0.30.3/go.mod h1:Ir9dlHfb8nRQsG3Qgo1zoGL+k1qMbcBtb8tcnsvzdAE=
github.com/AdguardTeam/urlfilter v0.20.0 h1:X32qiuVCVd8WDYCEsbdZKfXMzwdVqrdulamtUi4rmzs= github.com/AdguardTeam/urlfilter v0.20.0 h1:X32qiuVCVd8WDYCEsbdZKfXMzwdVqrdulamtUi4rmzs=
github.com/AdguardTeam/urlfilter v0.20.0/go.mod h1:gjrywLTxfJh6JOkwi9SU+frhP7kVVEZ5exFGkR99qpk= github.com/AdguardTeam/urlfilter v0.20.0/go.mod h1:gjrywLTxfJh6JOkwi9SU+frhP7kVVEZ5exFGkR99qpk=
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=

View file

@ -80,9 +80,8 @@ func (h *signalHandler) writePID(ctx context.Context) {
return return
} }
// Use 8, since most PIDs will fit. pid := os.Getpid()
data := make([]byte, 0, 8) data := strconv.AppendInt(nil, int64(pid), 10)
data = strconv.AppendInt(data, int64(os.Getpid()), 10)
data = append(data, '\n') data = append(data, '\n')
err := aghos.WriteFile(h.pidFile, data, 0o644) err := aghos.WriteFile(h.pidFile, data, 0o644)
@ -92,7 +91,7 @@ func (h *signalHandler) writePID(ctx context.Context) {
return return
} }
h.logger.DebugContext(ctx, "wrote pid", "file", h.pidFile) h.logger.DebugContext(ctx, "wrote pid", "file", h.pidFile, "pid", pid)
} }
// reconfigure rereads the configuration file and updates and restarts services. // reconfigure rereads the configuration file and updates and restarts services.

View file

@ -21,7 +21,7 @@ type config struct {
// type check // type check
var _ validator = (*config)(nil) var _ validator = (*config)(nil)
// validate returns an error if the configuration structure is invalid. // validate implements the [validator] interface for *config.
func (c *config) validate() (err error) { func (c *config) validate() (err error) {
if c == nil { if c == nil {
return errors.ErrNoValue return errors.ErrNoValue
@ -65,7 +65,7 @@ type dnsConfig struct {
// type check // type check
var _ validator = (*dnsConfig)(nil) var _ validator = (*dnsConfig)(nil)
// validate returns an error if the DNS configuration structure is invalid. // validate implements the [validator] interface for *dnsConfig.
// //
// TODO(a.garipov): Add more validations. // TODO(a.garipov): Add more validations.
func (c *dnsConfig) validate() (err error) { func (c *dnsConfig) validate() (err error) {
@ -74,7 +74,7 @@ func (c *dnsConfig) validate() (err error) {
case c == nil: case c == nil:
return errors.ErrNoValue return errors.ErrNoValue
case c.UpstreamTimeout.Duration <= 0: case c.UpstreamTimeout.Duration <= 0:
return newMustBePositiveError("upstream_timeout", c.UpstreamTimeout) return newErrNotPositive("upstream_timeout", c.UpstreamTimeout)
default: default:
return nil return nil
} }
@ -94,7 +94,7 @@ type httpConfig struct {
// type check // type check
var _ validator = (*httpConfig)(nil) var _ validator = (*httpConfig)(nil)
// validate returns an error if the HTTP configuration structure is invalid. // validate implements the [validator] interface for *httpConfig.
// //
// TODO(a.garipov): Add more validations. // TODO(a.garipov): Add more validations.
func (c *httpConfig) validate() (err error) { func (c *httpConfig) validate() (err error) {
@ -102,7 +102,7 @@ func (c *httpConfig) validate() (err error) {
case c == nil: case c == nil:
return errors.ErrNoValue return errors.ErrNoValue
case c.Timeout.Duration <= 0: case c.Timeout.Duration <= 0:
return newMustBePositiveError("timeout", c.Timeout) return newErrNotPositive("timeout", c.Timeout)
default: default:
return c.Pprof.validate() return c.Pprof.validate()
} }
@ -114,7 +114,10 @@ type httpPprofConfig struct {
Enabled bool `yaml:"enabled"` Enabled bool `yaml:"enabled"`
} }
// validate returns an error if the pprof configuration structure is invalid. // type check
var _ validator = (*httpPprofConfig)(nil)
// validate implements the [validator] interface for *httpPprofConfig.
func (c *httpPprofConfig) validate() (err error) { func (c *httpPprofConfig) validate() (err error) {
if c == nil { if c == nil {
return errors.ErrNoValue return errors.ErrNoValue
@ -132,7 +135,7 @@ type logConfig struct {
// type check // type check
var _ validator = (*logConfig)(nil) var _ validator = (*logConfig)(nil)
// validate returns an error if the HTTP configuration structure is invalid. // validate implements the [validator] interface for *logConfig.
// //
// TODO(a.garipov): Add more validations. // TODO(a.garipov): Add more validations.
func (c *logConfig) validate() (err error) { func (c *logConfig) validate() (err error) {

View file

@ -21,15 +21,11 @@ type numberOrDuration interface {
constraints.Integer | timeutil.Duration constraints.Integer | timeutil.Duration
} }
// newMustBePositiveError returns an error about the value that must be positive // newErrNotPositive returns an error about the value that must be positive but
// but isn't. prop is the name of the property to mention in the error message. // isn't. prop is the name of the property to mention in the error message.
// //
// TODO(a.garipov): Consider moving such helpers to golibs and use in AdGuardDNS // TODO(a.garipov): Consider moving such helpers to golibs and use in AdGuardDNS
// as well. // as well.
func newMustBePositiveError[T numberOrDuration](prop string, v T) (err error) { func newErrNotPositive[T numberOrDuration](prop string, v T) (err error) {
if s, ok := any(v).(fmt.Stringer); ok { return fmt.Errorf("%s: %w, got %v", prop, errors.ErrNotPositive, v)
return fmt.Errorf("%s: %w, got %s", prop, errors.ErrNotPositive, s)
}
return fmt.Errorf("%s: %w, got %d", prop, errors.ErrNotPositive, v)
} }

View file

@ -1,6 +1,11 @@
package websvc package websvc
import "net/http" import (
"log/slog"
"net/http"
"github.com/AdguardTeam/golibs/netutil/httputil"
)
// Path pattern constants. // Path pattern constants.
const ( const (
@ -21,3 +26,48 @@ const (
routePatternPatchV1SettingsDNS = http.MethodPatch + " " + PathPatternV1SettingsDNS routePatternPatchV1SettingsDNS = http.MethodPatch + " " + PathPatternV1SettingsDNS
routePatternPatchV1SettingsHTTP = http.MethodPatch + " " + PathPatternV1SettingsHTTP routePatternPatchV1SettingsHTTP = http.MethodPatch + " " + PathPatternV1SettingsHTTP
) )
// route registers all necessary handlers in mux.
func (svc *Service) route(mux *http.ServeMux) {
routes := []struct {
handler http.HandlerFunc
pattern string
isJSON bool
}{{
handler: svc.handleGetHealthCheck,
pattern: routePatternHealthCheck,
isJSON: false,
}, {
handler: http.FileServer(http.FS(svc.frontend)).ServeHTTP,
pattern: routePatternFrontend,
isJSON: false,
}, {
handler: svc.handleGetSettingsAll,
pattern: routePatternGetV1SettingsAll,
isJSON: true,
}, {
handler: svc.handlePatchSettingsDNS,
pattern: routePatternPatchV1SettingsDNS,
isJSON: true,
}, {
handler: svc.handlePatchSettingsHTTP,
pattern: routePatternPatchV1SettingsHTTP,
isJSON: true,
}, {
handler: svc.handleGetV1SystemInfo,
pattern: routePatternGetV1SystemInfo,
isJSON: true,
}}
logMw := httputil.NewLogMiddleware(svc.logger, slog.LevelDebug)
for _, r := range routes {
var hdlr http.Handler
if r.isJSON {
hdlr = jsonMw(r.handler)
} else {
hdlr = r.handler
}
mux.Handle(r.pattern, logMw.Wrap(hdlr))
}
}

View file

@ -83,7 +83,8 @@ func New(c *Config) (svc *Service, err error) {
forceHTTPS: c.ForceHTTPS, forceHTTPS: c.ForceHTTPS,
} }
mux := newMux(svc) mux := http.NewServeMux()
svc.route(mux)
if svc.overrideAddr != (netip.AddrPort{}) { if svc.overrideAddr != (netip.AddrPort{}) {
svc.servers = []*server{newServer(svc.logger, svc.overrideAddr, nil, mux, c.Timeout)} svc.servers = []*server{newServer(svc.logger, svc.overrideAddr, nil, mux, c.Timeout)}
@ -160,56 +161,6 @@ func newServer(
} }
} }
// newMux returns a new HTTP request multiplexer for the AdGuard Home web
// service.
func newMux(svc *Service) (mux *http.ServeMux) {
mux = http.NewServeMux()
routes := []struct {
handler http.HandlerFunc
pattern string
isJSON bool
}{{
handler: svc.handleGetHealthCheck,
pattern: routePatternHealthCheck,
isJSON: false,
}, {
handler: http.FileServer(http.FS(svc.frontend)).ServeHTTP,
pattern: routePatternFrontend,
isJSON: false,
}, {
handler: svc.handleGetSettingsAll,
pattern: routePatternGetV1SettingsAll,
isJSON: true,
}, {
handler: svc.handlePatchSettingsDNS,
pattern: routePatternPatchV1SettingsDNS,
isJSON: true,
}, {
handler: svc.handlePatchSettingsHTTP,
pattern: routePatternPatchV1SettingsHTTP,
isJSON: true,
}, {
handler: svc.handleGetV1SystemInfo,
pattern: routePatternGetV1SystemInfo,
isJSON: true,
}}
logMw := httputil.NewLogMiddleware(svc.logger, slog.LevelDebug)
for _, r := range routes {
var hdlr http.Handler
if r.isJSON {
hdlr = jsonMw(r.handler)
} else {
hdlr = r.handler
}
mux.Handle(r.pattern, logMw.Wrap(hdlr))
}
return mux
}
// addrs returns all addresses on which this server serves the HTTP API. addrs // addrs returns all addresses on which this server serves the HTTP API. addrs
// must not be called simultaneously with Start. If svc was initialized with // must not be called simultaneously with Start. If svc was initialized with
// ":0" addresses, addrs will not return the actual bound ports until Start is // ":0" addresses, addrs will not return the actual bound ports until Start is
@ -249,7 +200,7 @@ var _ agh.ServiceWithConfig[*Config] = (*Service)(nil)
// After Start exits, all HTTP servers have tried to start, possibly failing and // After Start exits, all HTTP servers have tried to start, possibly failing and
// writing error messages to the log. // writing error messages to the log.
// //
// TODO(a.garipov): Use the context. // TODO(a.garipov): Use the context for cancelation as well.
func (svc *Service) Start(ctx context.Context) (err error) { func (svc *Service) Start(ctx context.Context) (err error) {
if svc == nil { if svc == nil {
return nil return nil