mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2024-11-21 04:25:33 +03:00
next: upd more
This commit is contained in:
parent
05eec75222
commit
0c64e6cfc6
7 changed files with 74 additions and 76 deletions
3
go.mod
3
go.mod
|
@ -4,8 +4,7 @@ go 1.23.3
|
|||
|
||||
require (
|
||||
github.com/AdguardTeam/dnsproxy v0.73.3
|
||||
// TODO(a.garipov): !! Update to tag!
|
||||
github.com/AdguardTeam/golibs v0.30.3-0.20241108140605-ec84c9f86663
|
||||
github.com/AdguardTeam/golibs v0.30.3
|
||||
github.com/AdguardTeam/urlfilter v0.20.0
|
||||
github.com/NYTimes/gziphandler v1.1.1
|
||||
github.com/ameshkov/dnscrypt/v2 v2.3.0
|
||||
|
|
4
go.sum
4
go.sum
|
@ -1,7 +1,7 @@
|
|||
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/golibs v0.30.3-0.20241108140605-ec84c9f86663 h1:2uhyDq3f4BV48TjXDS0itBU2iwyuWKk1HGLujIJmbd0=
|
||||
github.com/AdguardTeam/golibs v0.30.3-0.20241108140605-ec84c9f86663/go.mod h1:Ir9dlHfb8nRQsG3Qgo1zoGL+k1qMbcBtb8tcnsvzdAE=
|
||||
github.com/AdguardTeam/golibs v0.30.3 h1:pRxLjMCJ1cZccjZWMMuKxzQQGEpFbmtyj4Tg7nk5rY0=
|
||||
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/go.mod h1:gjrywLTxfJh6JOkwi9SU+frhP7kVVEZ5exFGkR99qpk=
|
||||
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
||||
|
|
|
@ -80,9 +80,8 @@ func (h *signalHandler) writePID(ctx context.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
// Use 8, since most PIDs will fit.
|
||||
data := make([]byte, 0, 8)
|
||||
data = strconv.AppendInt(data, int64(os.Getpid()), 10)
|
||||
pid := os.Getpid()
|
||||
data := strconv.AppendInt(nil, int64(pid), 10)
|
||||
data = append(data, '\n')
|
||||
|
||||
err := aghos.WriteFile(h.pidFile, data, 0o644)
|
||||
|
@ -92,7 +91,7 @@ func (h *signalHandler) writePID(ctx context.Context) {
|
|||
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.
|
||||
|
|
|
@ -21,7 +21,7 @@ type config struct {
|
|||
// type check
|
||||
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) {
|
||||
if c == nil {
|
||||
return errors.ErrNoValue
|
||||
|
@ -65,7 +65,7 @@ type dnsConfig struct {
|
|||
// type check
|
||||
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.
|
||||
func (c *dnsConfig) validate() (err error) {
|
||||
|
@ -74,7 +74,7 @@ func (c *dnsConfig) validate() (err error) {
|
|||
case c == nil:
|
||||
return errors.ErrNoValue
|
||||
case c.UpstreamTimeout.Duration <= 0:
|
||||
return newMustBePositiveError("upstream_timeout", c.UpstreamTimeout)
|
||||
return newErrNotPositive("upstream_timeout", c.UpstreamTimeout)
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ type httpConfig struct {
|
|||
// type check
|
||||
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.
|
||||
func (c *httpConfig) validate() (err error) {
|
||||
|
@ -102,7 +102,7 @@ func (c *httpConfig) validate() (err error) {
|
|||
case c == nil:
|
||||
return errors.ErrNoValue
|
||||
case c.Timeout.Duration <= 0:
|
||||
return newMustBePositiveError("timeout", c.Timeout)
|
||||
return newErrNotPositive("timeout", c.Timeout)
|
||||
default:
|
||||
return c.Pprof.validate()
|
||||
}
|
||||
|
@ -114,7 +114,10 @@ type httpPprofConfig struct {
|
|||
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) {
|
||||
if c == nil {
|
||||
return errors.ErrNoValue
|
||||
|
@ -132,7 +135,7 @@ type logConfig struct {
|
|||
// type check
|
||||
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.
|
||||
func (c *logConfig) validate() (err error) {
|
||||
|
|
|
@ -21,15 +21,11 @@ type numberOrDuration interface {
|
|||
constraints.Integer | timeutil.Duration
|
||||
}
|
||||
|
||||
// newMustBePositiveError returns an error about the value that must be positive
|
||||
// but isn't. prop is the name of the property to mention in the error message.
|
||||
// newErrNotPositive returns an error about the value that must be positive but
|
||||
// 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
|
||||
// as well.
|
||||
func newMustBePositiveError[T numberOrDuration](prop string, v T) (err error) {
|
||||
if s, ok := any(v).(fmt.Stringer); ok {
|
||||
return fmt.Errorf("%s: %w, got %s", prop, errors.ErrNotPositive, s)
|
||||
}
|
||||
|
||||
return fmt.Errorf("%s: %w, got %d", prop, errors.ErrNotPositive, v)
|
||||
func newErrNotPositive[T numberOrDuration](prop string, v T) (err error) {
|
||||
return fmt.Errorf("%s: %w, got %v", prop, errors.ErrNotPositive, v)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
package websvc
|
||||
|
||||
import "net/http"
|
||||
import (
|
||||
"log/slog"
|
||||
"net/http"
|
||||
|
||||
"github.com/AdguardTeam/golibs/netutil/httputil"
|
||||
)
|
||||
|
||||
// Path pattern constants.
|
||||
const (
|
||||
|
@ -21,3 +26,48 @@ const (
|
|||
routePatternPatchV1SettingsDNS = http.MethodPatch + " " + PathPatternV1SettingsDNS
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,8 @@ func New(c *Config) (svc *Service, err error) {
|
|||
forceHTTPS: c.ForceHTTPS,
|
||||
}
|
||||
|
||||
mux := newMux(svc)
|
||||
mux := http.NewServeMux()
|
||||
svc.route(mux)
|
||||
|
||||
if svc.overrideAddr != (netip.AddrPort{}) {
|
||||
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
|
||||
// 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
|
||||
|
@ -249,7 +200,7 @@ var _ agh.ServiceWithConfig[*Config] = (*Service)(nil)
|
|||
// After Start exits, all HTTP servers have tried to start, possibly failing and
|
||||
// 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) {
|
||||
if svc == nil {
|
||||
return nil
|
||||
|
|
Loading…
Reference in a new issue