all: sync with master; upd chlog
This commit is contained in:
@@ -644,24 +644,27 @@ func optionalAuthHandler(handler http.Handler) http.Handler {
|
||||
return &authHandler{handler}
|
||||
}
|
||||
|
||||
// UserAdd - add new user
|
||||
func (a *Auth) UserAdd(u *webUser, password string) {
|
||||
// Add adds a new user with the given password.
|
||||
func (a *Auth) Add(u *webUser, password string) (err error) {
|
||||
if len(password) == 0 {
|
||||
return
|
||||
return errors.Error("empty password")
|
||||
}
|
||||
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
log.Error("bcrypt.GenerateFromPassword: %s", err)
|
||||
return
|
||||
return fmt.Errorf("generating hash: %w", err)
|
||||
}
|
||||
|
||||
u.PasswordHash = string(hash)
|
||||
|
||||
a.lock.Lock()
|
||||
a.users = append(a.users, *u)
|
||||
a.lock.Unlock()
|
||||
defer a.lock.Unlock()
|
||||
|
||||
log.Debug("auth: added user: %s", u.Name)
|
||||
a.users = append(a.users, *u)
|
||||
|
||||
log.Debug("auth: added user with login %q", u.Name)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// findUser returns a user if there is one.
|
||||
|
||||
@@ -47,7 +47,8 @@ func TestAuth(t *testing.T) {
|
||||
s := session{}
|
||||
|
||||
user := webUser{Name: "name"}
|
||||
a.UserAdd(&user, "password")
|
||||
err := a.Add(&user, "password")
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, checkSessionNotFound, a.checkSession("notfound"))
|
||||
a.RemoveSession("notfound")
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghio"
|
||||
"github.com/AdguardTeam/golibs/ioutil"
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
"github.com/josharian/native"
|
||||
)
|
||||
@@ -83,12 +83,7 @@ func glGetTokenDate(file string) uint32 {
|
||||
}
|
||||
}()
|
||||
|
||||
fileReader, err := aghio.LimitReader(f, MaxFileSize)
|
||||
if err != nil {
|
||||
log.Error("creating limited reader: %s", err)
|
||||
|
||||
return 0
|
||||
}
|
||||
fileReader := ioutil.LimitReader(f, MaxFileSize)
|
||||
|
||||
var dateToken uint32
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ type httpPprofConfig struct {
|
||||
// not absolutely necessary.
|
||||
type dnsConfig struct {
|
||||
BindHosts []netip.Addr `yaml:"bind_hosts"`
|
||||
Port int `yaml:"port"`
|
||||
Port uint16 `yaml:"port"`
|
||||
|
||||
// AnonymizeClientIP defines if clients' IP addresses should be anonymized
|
||||
// in query log and statistics.
|
||||
@@ -232,13 +232,13 @@ type tlsConfigSettings struct {
|
||||
Enabled bool `yaml:"enabled" json:"enabled"` // Enabled is the encryption (DoT/DoH/HTTPS) status
|
||||
ServerName string `yaml:"server_name" json:"server_name,omitempty"` // ServerName is the hostname of your HTTPS/TLS server
|
||||
ForceHTTPS bool `yaml:"force_https" json:"force_https"` // ForceHTTPS: if true, forces HTTP->HTTPS redirect
|
||||
PortHTTPS int `yaml:"port_https" json:"port_https,omitempty"` // HTTPS port. If 0, HTTPS will be disabled
|
||||
PortDNSOverTLS int `yaml:"port_dns_over_tls" json:"port_dns_over_tls,omitempty"` // DNS-over-TLS port. If 0, DoT will be disabled
|
||||
PortDNSOverQUIC int `yaml:"port_dns_over_quic" json:"port_dns_over_quic,omitempty"` // DNS-over-QUIC port. If 0, DoQ will be disabled
|
||||
PortHTTPS uint16 `yaml:"port_https" json:"port_https,omitempty"` // HTTPS port. If 0, HTTPS will be disabled
|
||||
PortDNSOverTLS uint16 `yaml:"port_dns_over_tls" json:"port_dns_over_tls,omitempty"` // DNS-over-TLS port. If 0, DoT will be disabled
|
||||
PortDNSOverQUIC uint16 `yaml:"port_dns_over_quic" json:"port_dns_over_quic,omitempty"` // DNS-over-QUIC port. If 0, DoQ will be disabled
|
||||
|
||||
// PortDNSCrypt is the port for DNSCrypt requests. If it's zero,
|
||||
// DNSCrypt is disabled.
|
||||
PortDNSCrypt int `yaml:"port_dnscrypt" json:"port_dnscrypt"`
|
||||
PortDNSCrypt uint16 `yaml:"port_dnscrypt" json:"port_dnscrypt"`
|
||||
// DNSCryptConfigFile is the path to the DNSCrypt config file. Must be
|
||||
// set if PortDNSCrypt is not zero.
|
||||
//
|
||||
@@ -262,7 +262,7 @@ type queryLogConfig struct {
|
||||
|
||||
// MemSize is the number of entries kept in memory before they are flushed
|
||||
// to disk.
|
||||
MemSize uint32 `yaml:"size_memory"`
|
||||
MemSize int `yaml:"size_memory"`
|
||||
|
||||
// Enabled defines if the query log is enabled.
|
||||
Enabled bool `yaml:"enabled"`
|
||||
@@ -554,10 +554,10 @@ func validateConfig() (err error) {
|
||||
}
|
||||
|
||||
// udpPort is the port number for UDP protocol.
|
||||
type udpPort int
|
||||
type udpPort uint16
|
||||
|
||||
// tcpPort is the port number for TCP protocol.
|
||||
type tcpPort int
|
||||
type tcpPort uint16
|
||||
|
||||
// addPorts is a helper for ports validation that skips zero ports.
|
||||
func addPorts[T tcpPort | udpPort](uc aghalg.UniqChecker[T], ports ...T) {
|
||||
|
||||
@@ -24,11 +24,9 @@ import (
|
||||
// addresses to a slice of strings.
|
||||
func appendDNSAddrs(dst []string, addrs ...netip.Addr) (res []string) {
|
||||
for _, addr := range addrs {
|
||||
var hostport string
|
||||
if config.DNS.Port != defaultPortDNS {
|
||||
hostport = netip.AddrPortFrom(addr, uint16(config.DNS.Port)).String()
|
||||
} else {
|
||||
hostport = addr.String()
|
||||
hostport := addr.String()
|
||||
if p := config.DNS.Port; p != defaultPortDNS {
|
||||
hostport = netutil.JoinHostPort(hostport, p)
|
||||
}
|
||||
|
||||
dst = append(dst, hostport)
|
||||
@@ -102,7 +100,7 @@ type statusResponse struct {
|
||||
Version string `json:"version"`
|
||||
Language string `json:"language"`
|
||||
DNSAddrs []string `json:"dns_addresses"`
|
||||
DNSPort int `json:"dns_port"`
|
||||
DNSPort uint16 `json:"dns_port"`
|
||||
HTTPPort uint16 `json:"http_port"`
|
||||
|
||||
// ProtectionDisabledDuration is the duration of the protection pause in
|
||||
@@ -340,7 +338,7 @@ func handleHTTPSRedirect(w http.ResponseWriter, r *http.Request) (proceed bool)
|
||||
var (
|
||||
forceHTTPS bool
|
||||
serveHTTP3 bool
|
||||
portHTTPS int
|
||||
portHTTPS uint16
|
||||
)
|
||||
func() {
|
||||
config.RLock()
|
||||
@@ -394,7 +392,7 @@ func handleHTTPSRedirect(w http.ResponseWriter, r *http.Request) (proceed bool)
|
||||
|
||||
// httpsURL returns a copy of u for redirection to the HTTPS version, taking the
|
||||
// hostname and the HTTPS port into account.
|
||||
func httpsURL(u *url.URL, host string, portHTTPS int) (redirectURL *url.URL) {
|
||||
func httpsURL(u *url.URL, host string, portHTTPS uint16) (redirectURL *url.URL) {
|
||||
hostPort := host
|
||||
if portHTTPS != defaultPortHTTPS {
|
||||
hostPort = netutil.JoinHostPort(host, portHTTPS)
|
||||
|
||||
@@ -43,8 +43,8 @@ func (web *webAPI) handleInstallGetAddresses(w http.ResponseWriter, r *http.Requ
|
||||
data := getAddrsResponse{
|
||||
Version: version.Version(),
|
||||
|
||||
WebPort: defaultPortHTTP,
|
||||
DNSPort: defaultPortDNS,
|
||||
WebPort: int(defaultPortHTTP),
|
||||
DNSPort: int(defaultPortDNS),
|
||||
}
|
||||
|
||||
ifaces, err := aghnet.GetValidNetInterfacesForWeb()
|
||||
@@ -64,7 +64,7 @@ func (web *webAPI) handleInstallGetAddresses(w http.ResponseWriter, r *http.Requ
|
||||
|
||||
type checkConfReqEnt struct {
|
||||
IP netip.Addr `json:"ip"`
|
||||
Port int `json:"port"`
|
||||
Port uint16 `json:"port"`
|
||||
Autofix bool `json:"autofix"`
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ func (req *checkConfReq) validateWeb(tcpPorts aghalg.UniqChecker[tcpPort]) (err
|
||||
defer func() { err = errors.Annotate(err, "validating ports: %w") }()
|
||||
|
||||
// TODO(a.garipov): Declare all port variables anywhere as uint16.
|
||||
reqPort := uint16(req.Web.Port)
|
||||
reqPort := req.Web.Port
|
||||
port := tcpPort(reqPort)
|
||||
addPorts(tcpPorts, port)
|
||||
if err = tcpPorts.Validate(); err != nil {
|
||||
@@ -128,7 +128,7 @@ func (req *checkConfReq) validateDNS(
|
||||
) (canAutofix bool, err error) {
|
||||
defer func() { err = errors.Annotate(err, "validating ports: %w") }()
|
||||
|
||||
port := uint16(req.DNS.Port)
|
||||
port := req.DNS.Port
|
||||
switch port {
|
||||
case 0:
|
||||
return false, nil
|
||||
@@ -142,13 +142,13 @@ func (req *checkConfReq) validateDNS(
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = aghnet.CheckPort("tcp", netip.AddrPortFrom(req.DNS.IP, uint16(port)))
|
||||
err = aghnet.CheckPort("tcp", netip.AddrPortFrom(req.DNS.IP, port))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
err = aghnet.CheckPort("udp", netip.AddrPortFrom(req.DNS.IP, uint16(port)))
|
||||
err = aghnet.CheckPort("udp", netip.AddrPortFrom(req.DNS.IP, port))
|
||||
if !aghnet.IsAddrInUse(err) {
|
||||
return false, err
|
||||
}
|
||||
@@ -160,7 +160,7 @@ func (req *checkConfReq) validateDNS(
|
||||
log.Error("disabling DNSStubListener: %s", err)
|
||||
}
|
||||
|
||||
err = aghnet.CheckPort("udp", netip.AddrPortFrom(req.DNS.IP, uint16(port)))
|
||||
err = aghnet.CheckPort("udp", netip.AddrPortFrom(req.DNS.IP, port))
|
||||
canAutofix = false
|
||||
}
|
||||
|
||||
@@ -305,7 +305,7 @@ func disableDNSStubListener() error {
|
||||
|
||||
type applyConfigReqEnt struct {
|
||||
IP netip.Addr `json:"ip"`
|
||||
Port int `json:"port"`
|
||||
Port uint16 `json:"port"`
|
||||
}
|
||||
|
||||
type applyConfigReq struct {
|
||||
@@ -395,14 +395,14 @@ func (web *webAPI) handleInstallConfigure(w http.ResponseWriter, r *http.Request
|
||||
return
|
||||
}
|
||||
|
||||
err = aghnet.CheckPort("udp", netip.AddrPortFrom(req.DNS.IP, uint16(req.DNS.Port)))
|
||||
err = aghnet.CheckPort("udp", netip.AddrPortFrom(req.DNS.IP, req.DNS.Port))
|
||||
if err != nil {
|
||||
aghhttp.Error(r, w, http.StatusBadRequest, "%s", err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
err = aghnet.CheckPort("tcp", netip.AddrPortFrom(req.DNS.IP, uint16(req.DNS.Port)))
|
||||
err = aghnet.CheckPort("tcp", netip.AddrPortFrom(req.DNS.IP, req.DNS.Port))
|
||||
if err != nil {
|
||||
aghhttp.Error(r, w, http.StatusBadRequest, "%s", err)
|
||||
|
||||
@@ -413,10 +413,22 @@ func (web *webAPI) handleInstallConfigure(w http.ResponseWriter, r *http.Request
|
||||
copyInstallSettings(curConfig, config)
|
||||
|
||||
Context.firstRun = false
|
||||
config.HTTPConfig.Address = netip.AddrPortFrom(req.Web.IP, uint16(req.Web.Port))
|
||||
config.HTTPConfig.Address = netip.AddrPortFrom(req.Web.IP, req.Web.Port)
|
||||
config.DNS.BindHosts = []netip.Addr{req.DNS.IP}
|
||||
config.DNS.Port = req.DNS.Port
|
||||
|
||||
u := &webUser{
|
||||
Name: req.Username,
|
||||
}
|
||||
err = Context.auth.Add(u, req.Password)
|
||||
if err != nil {
|
||||
Context.firstRun = true
|
||||
copyInstallSettings(config, curConfig)
|
||||
aghhttp.Error(r, w, http.StatusUnprocessableEntity, "%s", err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// TODO(e.burkov): StartMods() should be put in a separate goroutine at the
|
||||
// moment we'll allow setting up TLS in the initial configuration or the
|
||||
// configuration itself will use HTTPS protocol, because the underlying
|
||||
@@ -430,11 +442,6 @@ func (web *webAPI) handleInstallConfigure(w http.ResponseWriter, r *http.Request
|
||||
return
|
||||
}
|
||||
|
||||
u := &webUser{
|
||||
Name: req.Username,
|
||||
}
|
||||
Context.auth.UserAdd(u, req.Password)
|
||||
|
||||
err = config.write()
|
||||
if err != nil {
|
||||
Context.firstRun = true
|
||||
@@ -445,8 +452,7 @@ func (web *webAPI) handleInstallConfigure(w http.ResponseWriter, r *http.Request
|
||||
}
|
||||
|
||||
web.conf.firstRun = false
|
||||
web.conf.BindHost = req.Web.IP
|
||||
web.conf.BindPort = req.Web.Port
|
||||
web.conf.BindAddr = netip.AddrPortFrom(req.Web.IP, req.Web.Port)
|
||||
|
||||
registerControlHandlers(web)
|
||||
|
||||
@@ -487,9 +493,9 @@ func decodeApplyConfigReq(r io.Reader) (req *applyConfigReq, restartHTTP bool, e
|
||||
}
|
||||
|
||||
addrPort := config.HTTPConfig.Address
|
||||
restartHTTP = addrPort.Addr() != req.Web.IP || int(addrPort.Port()) != req.Web.Port
|
||||
restartHTTP = addrPort.Addr() != req.Web.IP || addrPort.Port() != req.Web.Port
|
||||
if restartHTTP {
|
||||
err = aghnet.CheckPort("tcp", netip.AddrPortFrom(req.Web.IP, uint16(req.Web.Port)))
|
||||
err = aghnet.CheckPort("tcp", netip.AddrPortFrom(req.Web.IP, req.Web.Port))
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf(
|
||||
"checking address %s:%d: %w",
|
||||
|
||||
@@ -27,11 +27,11 @@ import (
|
||||
|
||||
// Default listening ports.
|
||||
const (
|
||||
defaultPortDNS = 53
|
||||
defaultPortHTTP = 80
|
||||
defaultPortHTTPS = 443
|
||||
defaultPortQUIC = 853
|
||||
defaultPortTLS = 853
|
||||
defaultPortDNS uint16 = 53
|
||||
defaultPortHTTP uint16 = 80
|
||||
defaultPortHTTPS uint16 = 443
|
||||
defaultPortQUIC uint16 = 853
|
||||
defaultPortTLS uint16 = 853
|
||||
)
|
||||
|
||||
// Called by other modules when configuration is changed
|
||||
@@ -196,27 +196,27 @@ func isRunning() bool {
|
||||
return Context.dnsServer != nil && Context.dnsServer.IsRunning()
|
||||
}
|
||||
|
||||
func ipsToTCPAddrs(ips []netip.Addr, port int) (tcpAddrs []*net.TCPAddr) {
|
||||
func ipsToTCPAddrs(ips []netip.Addr, port uint16) (tcpAddrs []*net.TCPAddr) {
|
||||
if ips == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
tcpAddrs = make([]*net.TCPAddr, 0, len(ips))
|
||||
for _, ip := range ips {
|
||||
tcpAddrs = append(tcpAddrs, net.TCPAddrFromAddrPort(netip.AddrPortFrom(ip, uint16(port))))
|
||||
tcpAddrs = append(tcpAddrs, net.TCPAddrFromAddrPort(netip.AddrPortFrom(ip, port)))
|
||||
}
|
||||
|
||||
return tcpAddrs
|
||||
}
|
||||
|
||||
func ipsToUDPAddrs(ips []netip.Addr, port int) (udpAddrs []*net.UDPAddr) {
|
||||
func ipsToUDPAddrs(ips []netip.Addr, port uint16) (udpAddrs []*net.UDPAddr) {
|
||||
if ips == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
udpAddrs = make([]*net.UDPAddr, 0, len(ips))
|
||||
for _, ip := range ips {
|
||||
udpAddrs = append(udpAddrs, net.UDPAddrFromAddrPort(netip.AddrPortFrom(ip, uint16(port))))
|
||||
udpAddrs = append(udpAddrs, net.UDPAddrFromAddrPort(netip.AddrPortFrom(ip, port)))
|
||||
}
|
||||
|
||||
return udpAddrs
|
||||
@@ -346,8 +346,8 @@ func getDNSEncryption() (de dnsEncryption) {
|
||||
hostname := tlsConf.ServerName
|
||||
if tlsConf.PortHTTPS != 0 {
|
||||
addr := hostname
|
||||
if tlsConf.PortHTTPS != defaultPortHTTPS {
|
||||
addr = netutil.JoinHostPort(addr, tlsConf.PortHTTPS)
|
||||
if p := tlsConf.PortHTTPS; p != defaultPortHTTPS {
|
||||
addr = netutil.JoinHostPort(addr, p)
|
||||
}
|
||||
|
||||
de.https = (&url.URL{
|
||||
@@ -357,17 +357,17 @@ func getDNSEncryption() (de dnsEncryption) {
|
||||
}).String()
|
||||
}
|
||||
|
||||
if tlsConf.PortDNSOverTLS != 0 {
|
||||
if p := tlsConf.PortDNSOverTLS; p != 0 {
|
||||
de.tls = (&url.URL{
|
||||
Scheme: "tls",
|
||||
Host: netutil.JoinHostPort(hostname, tlsConf.PortDNSOverTLS),
|
||||
Host: netutil.JoinHostPort(hostname, p),
|
||||
}).String()
|
||||
}
|
||||
|
||||
if tlsConf.PortDNSOverQUIC != 0 {
|
||||
if p := tlsConf.PortDNSOverQUIC; p != 0 {
|
||||
de.quic = (&url.URL{
|
||||
Scheme: "quic",
|
||||
Host: netutil.JoinHostPort(hostname, tlsConf.PortDNSOverQUIC),
|
||||
Host: netutil.JoinHostPort(hostname, p),
|
||||
}).String()
|
||||
}
|
||||
}
|
||||
@@ -494,7 +494,9 @@ func closeDNSServer() {
|
||||
Context.dnsServer = nil
|
||||
}
|
||||
|
||||
Context.filters.Close()
|
||||
if Context.filters != nil {
|
||||
Context.filters.Close()
|
||||
}
|
||||
|
||||
if Context.stats != nil {
|
||||
err := Context.stats.Close()
|
||||
|
||||
@@ -9,8 +9,10 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sync"
|
||||
@@ -327,7 +329,7 @@ func setupBindOpts(opts options) (err error) {
|
||||
if opts.bindPort != 0 {
|
||||
config.HTTPConfig.Address = netip.AddrPortFrom(
|
||||
config.HTTPConfig.Address.Addr(),
|
||||
uint16(opts.bindPort),
|
||||
opts.bindPort,
|
||||
)
|
||||
|
||||
err = checkPorts()
|
||||
@@ -495,8 +497,7 @@ func initWeb(opts options, clientBuildFS fs.FS, upd *updater.Updater) (web *webA
|
||||
|
||||
clientFS: clientFS,
|
||||
|
||||
BindHost: config.HTTPConfig.Address.Addr(),
|
||||
BindPort: int(config.HTTPConfig.Address.Port()),
|
||||
BindAddr: config.HTTPConfig.Address,
|
||||
|
||||
ReadTimeout: readTimeout,
|
||||
ReadHeaderTimeout: readHdrTimeout,
|
||||
@@ -559,16 +560,28 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}) {
|
||||
err = setupOpts(opts)
|
||||
fatalOnError(err)
|
||||
|
||||
execPath, err := os.Executable()
|
||||
fatalOnError(errors.Annotate(err, "getting executable path: %w"))
|
||||
|
||||
u := &url.URL{
|
||||
Scheme: "https",
|
||||
// TODO(a.garipov): Make configurable.
|
||||
Host: "static.adtidy.org",
|
||||
Path: path.Join("adguardhome", version.Channel(), "version.json"),
|
||||
}
|
||||
|
||||
upd := updater.NewUpdater(&updater.Config{
|
||||
Client: config.Filtering.HTTPClient,
|
||||
Version: version.Version(),
|
||||
Channel: version.Channel(),
|
||||
GOARCH: runtime.GOARCH,
|
||||
GOOS: runtime.GOOS,
|
||||
GOARM: version.GOARM(),
|
||||
GOMIPS: version.GOMIPS(),
|
||||
WorkDir: Context.workDir,
|
||||
ConfName: config.getConfigFilename(),
|
||||
Client: config.Filtering.HTTPClient,
|
||||
Version: version.Version(),
|
||||
Channel: version.Channel(),
|
||||
GOARCH: runtime.GOARCH,
|
||||
GOOS: runtime.GOOS,
|
||||
GOARM: version.GOARM(),
|
||||
GOMIPS: version.GOMIPS(),
|
||||
WorkDir: Context.workDir,
|
||||
ConfName: config.getConfigFilename(),
|
||||
ExecPath: execPath,
|
||||
VersionCheckURL: u.String(),
|
||||
})
|
||||
|
||||
// TODO(e.burkov): This could be made earlier, probably as the option's
|
||||
@@ -839,7 +852,7 @@ func loadCmdLineOpts() (opts options) {
|
||||
// example:
|
||||
//
|
||||
// go to http://127.0.0.1:80
|
||||
func printWebAddrs(proto, addr string, port int) {
|
||||
func printWebAddrs(proto, addr string, port uint16) {
|
||||
log.Printf("go to %s://%s", proto, netutil.JoinHostPort(addr, port))
|
||||
}
|
||||
|
||||
@@ -851,7 +864,7 @@ func printHTTPAddresses(proto string) {
|
||||
Context.tls.WriteDiskConfig(&tlsConf)
|
||||
}
|
||||
|
||||
port := int(config.HTTPConfig.Address.Port())
|
||||
port := config.HTTPConfig.Address.Port()
|
||||
if proto == aghhttp.SchemeHTTPS {
|
||||
port = tlsConf.PortHTTPS
|
||||
}
|
||||
|
||||
@@ -4,9 +4,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghio"
|
||||
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
"github.com/AdguardTeam/golibs/ioutil"
|
||||
)
|
||||
|
||||
// middlerware is a wrapper function signature.
|
||||
@@ -23,12 +21,14 @@ func withMiddlewares(h http.Handler, middlewares ...middleware) (wrapped http.Ha
|
||||
return wrapped
|
||||
}
|
||||
|
||||
// defaultReqBodySzLim is the default maximum request body size.
|
||||
const defaultReqBodySzLim = 64 * 1024
|
||||
const (
|
||||
// defaultReqBodySzLim is the default maximum request body size.
|
||||
defaultReqBodySzLim = 64 * 1024
|
||||
|
||||
// largerReqBodySzLim is the maximum request body size for APIs expecting larger
|
||||
// requests.
|
||||
const largerReqBodySzLim = 4 * 1024 * 1024
|
||||
// largerReqBodySzLim is the maximum request body size for APIs expecting
|
||||
// larger requests.
|
||||
largerReqBodySzLim = 4 * 1024 * 1024
|
||||
)
|
||||
|
||||
// expectsLargerRequests shows if this request should use a larger body size
|
||||
// limit. These are exceptions for poorly designed current APIs as well as APIs
|
||||
@@ -52,20 +52,12 @@ func expectsLargerRequests(r *http.Request) (ok bool) {
|
||||
// method limited.
|
||||
func limitRequestBody(h http.Handler) (limited http.Handler) {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
var err error
|
||||
|
||||
var szLim int64 = defaultReqBodySzLim
|
||||
var szLim uint64 = defaultReqBodySzLim
|
||||
if expectsLargerRequests(r) {
|
||||
szLim = largerReqBodySzLim
|
||||
}
|
||||
|
||||
var reader io.Reader
|
||||
reader, err = aghio.LimitReader(r.Body, szLim)
|
||||
if err != nil {
|
||||
log.Error("limitRequestBody: %s", err)
|
||||
|
||||
return
|
||||
}
|
||||
reader := ioutil.LimitReader(r.Body, szLim)
|
||||
|
||||
// HTTP handlers aren't supposed to call r.Body.Close(), so just
|
||||
// replace the body in a clone.
|
||||
|
||||
@@ -7,13 +7,13 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghio"
|
||||
"github.com/AdguardTeam/golibs/ioutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestLimitRequestBody(t *testing.T) {
|
||||
errReqLimitReached := &aghio.LimitReachedError{
|
||||
errReqLimitReached := &ioutil.LimitError{
|
||||
Limit: defaultReqBodySzLim,
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ type options struct {
|
||||
// bindPort is the port on which to serve the HTTP UI.
|
||||
//
|
||||
// Deprecated: Use bindAddr.
|
||||
bindPort int
|
||||
bindPort uint16
|
||||
|
||||
// bindAddr is the address to serve the web UI on.
|
||||
bindAddr netip.AddrPort
|
||||
@@ -160,15 +160,11 @@ var cmdLineOpts = []cmdLineOpt{{
|
||||
shortName: "h",
|
||||
}, {
|
||||
updateWithValue: func(o options, v string) (options, error) {
|
||||
var err error
|
||||
var p int
|
||||
minPort, maxPort := 0, 1<<16-1
|
||||
if p, err = strconv.Atoi(v); err != nil {
|
||||
err = fmt.Errorf("port %q is not a number", v)
|
||||
} else if p < minPort || p > maxPort {
|
||||
err = fmt.Errorf("port %d not in range %d - %d", p, minPort, maxPort)
|
||||
p, err := strconv.ParseUint(v, 10, 16)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("parsing port: %w", err)
|
||||
} else {
|
||||
o.bindPort = p
|
||||
o.bindPort = uint16(p)
|
||||
}
|
||||
|
||||
return o, err
|
||||
@@ -180,7 +176,7 @@ var cmdLineOpts = []cmdLineOpt{{
|
||||
return "", false
|
||||
}
|
||||
|
||||
return strconv.Itoa(o.bindPort), true
|
||||
return strconv.Itoa(int(o.bindPort)), true
|
||||
},
|
||||
description: "Deprecated. Port to serve HTTP pages on. Use --web-addr.",
|
||||
longName: "port",
|
||||
|
||||
@@ -67,11 +67,11 @@ func TestParseBindHost(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestParseBindPort(t *testing.T) {
|
||||
assert.Equal(t, 0, testParseOK(t).bindPort, "empty is port 0")
|
||||
assert.Equal(t, 65535, testParseOK(t, "-p", "65535").bindPort, "-p is port")
|
||||
assert.Equal(t, uint16(0), testParseOK(t).bindPort, "empty is port 0")
|
||||
assert.Equal(t, uint16(65535), testParseOK(t, "-p", "65535").bindPort, "-p is port")
|
||||
testParseParamMissing(t, "-p")
|
||||
|
||||
assert.Equal(t, 65535, testParseOK(t, "--port", "65535").bindPort, "--port is port")
|
||||
assert.Equal(t, uint16(65535), testParseOK(t, "--port", "65535").bindPort, "--port is port")
|
||||
testParseParamMissing(t, "--port")
|
||||
|
||||
testParseErr(t, "not an int", "-p", "x")
|
||||
|
||||
@@ -39,8 +39,8 @@ type webConfig struct {
|
||||
|
||||
clientFS fs.FS
|
||||
|
||||
BindHost netip.Addr
|
||||
BindPort int
|
||||
// BindAddr is the binding address with port for plain HTTP web interface.
|
||||
BindAddr netip.AddrPort
|
||||
|
||||
// ReadTimeout is an option to pass to http.Server for setting an
|
||||
// appropriate field.
|
||||
@@ -125,12 +125,12 @@ func newWebAPI(conf *webConfig) (w *webAPI) {
|
||||
// available, unless the HTTPS server isn't active.
|
||||
//
|
||||
// TODO(a.garipov): Adapt for HTTP/3.
|
||||
func webCheckPortAvailable(port int) (ok bool) {
|
||||
func webCheckPortAvailable(port uint16) (ok bool) {
|
||||
if Context.web.httpsServer.server != nil {
|
||||
return true
|
||||
}
|
||||
|
||||
addrPort := netip.AddrPortFrom(config.HTTPConfig.Address.Addr(), uint16(port))
|
||||
addrPort := netip.AddrPortFrom(config.HTTPConfig.Address.Addr(), port)
|
||||
|
||||
return aghnet.CheckPort("tcp", addrPort) == nil
|
||||
}
|
||||
@@ -185,10 +185,9 @@ func (web *webAPI) start() {
|
||||
hdlr := h2c.NewHandler(withMiddlewares(Context.mux, limitRequestBody), &http2.Server{})
|
||||
|
||||
// Create a new instance, because the Web is not usable after Shutdown.
|
||||
hostStr := web.conf.BindHost.String()
|
||||
web.httpServer = &http.Server{
|
||||
ErrorLog: log.StdLog("web: plain", log.DEBUG),
|
||||
Addr: netutil.JoinHostPort(hostStr, web.conf.BindPort),
|
||||
Addr: web.conf.BindAddr.String(),
|
||||
Handler: hdlr,
|
||||
ReadTimeout: web.conf.ReadTimeout,
|
||||
ReadHeaderTimeout: web.conf.ReadHeaderTimeout,
|
||||
@@ -249,7 +248,7 @@ func (web *webAPI) tlsServerLoop() {
|
||||
|
||||
web.httpsServer.cond.L.Unlock()
|
||||
|
||||
var portHTTPS int
|
||||
var portHTTPS uint16
|
||||
func() {
|
||||
config.RLock()
|
||||
defer config.RUnlock()
|
||||
@@ -257,7 +256,7 @@ func (web *webAPI) tlsServerLoop() {
|
||||
portHTTPS = config.TLS.PortHTTPS
|
||||
}()
|
||||
|
||||
addr := netutil.JoinHostPort(web.conf.BindHost.String(), portHTTPS)
|
||||
addr := netip.AddrPortFrom(web.conf.BindAddr.Addr(), portHTTPS).String()
|
||||
web.httpsServer.server = &http.Server{
|
||||
ErrorLog: log.StdLog("web: https", log.DEBUG),
|
||||
Addr: addr,
|
||||
|
||||
Reference in New Issue
Block a user