Pull request 2354: AGDNS-2690-global-context-tls

Merge in DNS/adguard-home from AGDNS-2690-global-context-tls to master

Squashed commit of the following:

commit ae1d9e6f3f3b8abefbc5e776eb256577f7fbbb0f
Merge: 6f30f488a bf9be98c7
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Mar 10 18:15:24 2025 +0300

    Merge branch 'master' into AGDNS-2690-global-context-tls

commit 6f30f488aa2305e518000dc6c1028ede83bf1cc6
Merge: baa187ab0 66fba942c
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Mar 10 15:08:47 2025 +0300

    Merge branch 'master' into AGDNS-2690-global-context-tls

commit baa187ab0b6db7f41e49dece7b4d0430409e7cae
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Mon Mar 10 15:08:39 2025 +0300

    home: imp docs

commit 96a09389c5049a84bb30ed285cc5e1df9aaa438f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Mar 6 20:15:05 2025 +0300

    home: imp docs

commit 1cd007707af4a7a5160c8fe21b20b84543d59e5a
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Mar 6 18:54:07 2025 +0300

    home: imp docs

commit ad3d2b6616c2c3aba566a2158ffc597e5802929f
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Tue Mar 4 19:38:45 2025 +0300

    home: global context tls
This commit is contained in:
Stanislav Chzhen
2025-03-10 18:24:41 +03:00
parent bf9be98c71
commit 3255efcaf3
10 changed files with 103 additions and 89 deletions

View File

@@ -640,7 +640,7 @@ func readConfigFile() (fileData []byte, err error) {
} }
// Saves configuration to the YAML file and also saves the user filter contents to a file // Saves configuration to the YAML file and also saves the user filter contents to a file
func (c *configuration) write() (err error) { func (c *configuration) write(tlsMgr *tlsManager) (err error) {
c.Lock() c.Lock()
defer c.Unlock() defer c.Unlock()
@@ -648,9 +648,9 @@ func (c *configuration) write() (err error) {
config.Users = globalContext.auth.usersList() config.Users = globalContext.auth.usersList()
} }
if globalContext.tls != nil { if tlsMgr != nil {
tlsConf := tlsConfigSettings{} tlsConf := tlsConfigSettings{}
globalContext.tls.WriteDiskConfig(&tlsConf) tlsMgr.WriteDiskConfig(&tlsConf)
config.TLS = tlsConf config.TLS = tlsConf
} }

View File

@@ -68,7 +68,8 @@ func appendDNSAddrsWithIfaces(dst []string, src []netip.Addr) (res []string, err
// collectDNSAddresses returns the list of DNS addresses the server is listening // collectDNSAddresses returns the list of DNS addresses the server is listening
// on, including the addresses on all interfaces in cases of unspecified IPs. // on, including the addresses on all interfaces in cases of unspecified IPs.
func collectDNSAddresses() (addrs []string, err error) { // tlsMgr must not be nil.
func collectDNSAddresses(tlsMgr *tlsManager) (addrs []string, err error) {
if hosts := config.DNS.BindHosts; len(hosts) == 0 { if hosts := config.DNS.BindHosts; len(hosts) == 0 {
addrs = appendDNSAddrs(addrs, netutil.IPv4Localhost()) addrs = appendDNSAddrs(addrs, netutil.IPv4Localhost())
} else { } else {
@@ -78,7 +79,7 @@ func collectDNSAddresses() (addrs []string, err error) {
} }
} }
de := getDNSEncryption() de := getDNSEncryption(tlsMgr)
if de.https != "" { if de.https != "" {
addrs = append(addrs, de.https) addrs = append(addrs, de.https)
} }
@@ -113,8 +114,8 @@ type statusResponse struct {
IsRunning bool `json:"running"` IsRunning bool `json:"running"`
} }
func handleStatus(w http.ResponseWriter, r *http.Request) { func (web *webAPI) handleStatus(w http.ResponseWriter, r *http.Request) {
dnsAddrs, err := collectDNSAddresses() dnsAddrs, err := collectDNSAddresses(web.tlsManager)
if err != nil { if err != nil {
// Don't add a lot of formatting, since the error is already // Don't add a lot of formatting, since the error is already
// wrapped by collectDNSAddresses. // wrapped by collectDNSAddresses.
@@ -167,9 +168,8 @@ func handleStatus(w http.ResponseWriter, r *http.Request) {
aghhttp.WriteJSONResponseOK(w, r, resp) aghhttp.WriteJSONResponseOK(w, r, resp)
} }
// ------------------------ // registerControlHandlers sets up HTTP handlers for various control endpoints.
// registration of handlers // web must not be nil.
// ------------------------
func registerControlHandlers(web *webAPI) { func registerControlHandlers(web *webAPI) {
globalContext.mux.HandleFunc( globalContext.mux.HandleFunc(
"/control/version.json", "/control/version.json",
@@ -177,7 +177,7 @@ func registerControlHandlers(web *webAPI) {
) )
httpRegister(http.MethodPost, "/control/update", web.handleUpdate) httpRegister(http.MethodPost, "/control/update", web.handleUpdate)
httpRegister(http.MethodGet, "/control/status", handleStatus) httpRegister(http.MethodGet, "/control/status", web.handleStatus)
httpRegister(http.MethodPost, "/control/i18n/change_language", handleI18nChangeLanguage) httpRegister(http.MethodPost, "/control/i18n/change_language", handleI18nChangeLanguage)
httpRegister(http.MethodGet, "/control/i18n/current_language", handleI18nCurrentLanguage) httpRegister(http.MethodGet, "/control/i18n/current_language", handleI18nCurrentLanguage)
httpRegister(http.MethodGet, "/control/profile", handleGetProfile) httpRegister(http.MethodGet, "/control/profile", handleGetProfile)
@@ -189,6 +189,7 @@ func registerControlHandlers(web *webAPI) {
RegisterAuthHandlers() RegisterAuthHandlers()
} }
// httpRegister registers an HTTP handler.
func httpRegister(method, url string, handler http.HandlerFunc) { func httpRegister(method, url string, handler http.HandlerFunc) {
if method == "" { if method == "" {
// "/dns-query" handler doesn't need auth, gzip and isn't restricted by 1 HTTP method // "/dns-query" handler doesn't need auth, gzip and isn't restricted by 1 HTTP method

View File

@@ -452,7 +452,7 @@ func (web *webAPI) handleInstallConfigure(w http.ResponseWriter, r *http.Request
// moment we'll allow setting up TLS in the initial configuration or the // moment we'll allow setting up TLS in the initial configuration or the
// configuration itself will use HTTPS protocol, because the underlying // configuration itself will use HTTPS protocol, because the underlying
// functions potentially restart the HTTPS server. // functions potentially restart the HTTPS server.
err = startMods(web.baseLogger) err = startMods(r.Context(), web.baseLogger, web.tlsManager)
if err != nil { if err != nil {
globalContext.firstRun = true globalContext.firstRun = true
copyInstallSettings(config, curConfig) copyInstallSettings(config, curConfig)
@@ -461,7 +461,7 @@ func (web *webAPI) handleInstallConfigure(w http.ResponseWriter, r *http.Request
return return
} }
err = config.write() err = config.write(web.tlsManager)
if err != nil { if err != nil {
globalContext.firstRun = true globalContext.firstRun = true
copyInstallSettings(config, curConfig) copyInstallSettings(config, curConfig)
@@ -527,6 +527,31 @@ func decodeApplyConfigReq(r io.Reader) (req *applyConfigReq, restartHTTP bool, e
return req, restartHTTP, err return req, restartHTTP, err
} }
// startMods initializes and starts the DNS server after installation.
// baseLogger and tlsMgr must not be nil.
func startMods(ctx context.Context, baseLogger *slog.Logger, tlsMgr *tlsManager) (err error) {
statsDir, querylogDir, err := checkStatsAndQuerylogDirs(&globalContext, config)
if err != nil {
return err
}
err = initDNS(baseLogger, tlsMgr, statsDir, querylogDir)
if err != nil {
return err
}
tlsMgr.start(ctx)
err = startDNSServer()
if err != nil {
closeDNSServer()
return err
}
return nil
}
func (web *webAPI) registerInstallHandlers() { func (web *webAPI) registerInstallHandlers() {
globalContext.mux.HandleFunc("/control/install/get_addresses", preInstall(ensureGET(web.handleInstallGetAddresses))) globalContext.mux.HandleFunc("/control/install/get_addresses", preInstall(ensureGET(web.handleInstallGetAddresses)))
globalContext.mux.HandleFunc("/control/install/check_config", preInstall(ensurePOST(web.handleInstallCheckConfig))) globalContext.mux.HandleFunc("/control/install/check_config", preInstall(ensurePOST(web.handleInstallCheckConfig)))

View File

@@ -62,7 +62,7 @@ func (web *webAPI) handleVersionJSON(w http.ResponseWriter, r *http.Request) {
return return
} }
err = resp.setAllowedToAutoUpdate() err = resp.setAllowedToAutoUpdate(web.tlsManager)
if err != nil { if err != nil {
// Don't wrap the error, because it's informative enough as is. // Don't wrap the error, because it's informative enough as is.
aghhttp.Error(r, w, http.StatusInternalServerError, "%s", err) aghhttp.Error(r, w, http.StatusInternalServerError, "%s", err)
@@ -158,14 +158,14 @@ type versionResponse struct {
} }
// setAllowedToAutoUpdate sets CanAutoUpdate to true if AdGuard Home is actually // setAllowedToAutoUpdate sets CanAutoUpdate to true if AdGuard Home is actually
// allowed to perform an automatic update by the OS. // allowed to perform an automatic update by the OS. tlsMgr must not be nil.
func (vr *versionResponse) setAllowedToAutoUpdate() (err error) { func (vr *versionResponse) setAllowedToAutoUpdate(tlsMgr *tlsManager) (err error) {
if vr.CanAutoUpdate != aghalg.NBTrue { if vr.CanAutoUpdate != aghalg.NBTrue {
return nil return nil
} }
tlsConf := &tlsConfigSettings{} tlsConf := &tlsConfigSettings{}
globalContext.tls.WriteDiskConfig(tlsConf) tlsMgr.WriteDiskConfig(tlsConf)
canUpdate := true canUpdate := true
if tlsConfUsesPrivilegedPorts(tlsConf) || if tlsConfUsesPrivilegedPorts(tlsConf) ||

View File

@@ -39,16 +39,22 @@ const (
// Called by other modules when configuration is changed // Called by other modules when configuration is changed
func onConfigModified() { func onConfigModified() {
err := config.write() err := config.write(globalContext.tls)
if err != nil { if err != nil {
log.Error("writing config: %s", err) log.Error("writing config: %s", err)
} }
} }
// initDNS updates all the fields of the [globalContext] needed to initialize the DNS // initDNS updates all the fields of the [globalContext] needed to initialize
// server and initializes it at last. It also must not be called unless // the DNS server and initializes it at last. It also must not be called unless
// [config] and [globalContext] are initialized. baseLogger must not be nil. // [config] and [globalContext] are initialized. baseLogger and tlsMgr must not
func initDNS(baseLogger *slog.Logger, statsDir, querylogDir string) (err error) { // be nil.
func initDNS(
baseLogger *slog.Logger,
tlsMgr *tlsManager,
statsDir string,
querylogDir string,
) (err error) {
anonymizer := config.anonymizer() anonymizer := config.anonymizer()
statsConf := stats.Config{ statsConf := stats.Config{
@@ -104,7 +110,7 @@ func initDNS(baseLogger *slog.Logger, statsDir, querylogDir string) (err error)
} }
tlsConf := &tlsConfigSettings{} tlsConf := &tlsConfigSettings{}
globalContext.tls.WriteDiskConfig(tlsConf) tlsMgr.WriteDiskConfig(tlsConf)
return initDNSServer( return initDNSServer(
globalContext.filters, globalContext.filters,
@@ -357,16 +363,18 @@ func newDNSCryptConfig(
}, nil }, nil
} }
// dnsEncryption contains different types of TLS encryption addresses.
type dnsEncryption struct { type dnsEncryption struct {
https string https string
tls string tls string
quic string quic string
} }
func getDNSEncryption() (de dnsEncryption) { // getDNSEncryption returns the TLS encryption addresses that AdGuard Home
// listens on. tlsMgr must not be nil.
func getDNSEncryption(tlsMgr *tlsManager) (de dnsEncryption) {
tlsConf := tlsConfigSettings{} tlsConf := tlsConfigSettings{}
tlsMgr.WriteDiskConfig(&tlsConf)
globalContext.tls.WriteDiskConfig(&tlsConf)
if !tlsConf.Enabled || len(tlsConf.ServerName) == 0 { if !tlsConf.Enabled || len(tlsConf.ServerName) == 0 {
return dnsEncryption{} return dnsEncryption{}
@@ -487,9 +495,11 @@ func startDNSServer() error {
return nil return nil
} }
func reconfigureDNSServer() (err error) { // reconfigureDNSServer updates the DNS server configuration using the provided
// TLS settings. tlsMgr must not be nil.
func reconfigureDNSServer(tlsMgr *tlsManager) (err error) {
tlsConf := &tlsConfigSettings{} tlsConf := &tlsConfigSettings{}
globalContext.tls.WriteDiskConfig(tlsConf) tlsMgr.WriteDiskConfig(tlsConf)
newConf, err := newServerConfig( newConf, err := newServerConfig(
&config.DNS, &config.DNS,

View File

@@ -57,7 +57,12 @@ type homeContext struct {
auth *Auth // HTTP authentication module auth *Auth // HTTP authentication module
filters *filtering.DNSFilter // DNS filtering module filters *filtering.DNSFilter // DNS filtering module
web *webAPI // Web (HTTP, HTTPS) module web *webAPI // Web (HTTP, HTTPS) module
tls *tlsManager // TLS module
// tls contains the current configuration and state of TLS encryption.
//
// TODO(s.chzhen): Remove once it is no longer called from different
// modules. See [onConfigModified].
tls *tlsManager
// etcHosts contains IP-hostname mappings taken from the OS-specific hosts // etcHosts contains IP-hostname mappings taken from the OS-specific hosts
// configuration files, for example /etc/hosts. // configuration files, for example /etc/hosts.
@@ -519,13 +524,15 @@ func isUpdateEnabled(ctx context.Context, l *slog.Logger, opts *options, customU
} }
} }
// initWeb initializes the web module. upd and baseLogger must not be nil. // initWeb initializes the web module. upd, baseLogger, and tlsMgr must not be
// nil.
func initWeb( func initWeb(
ctx context.Context, ctx context.Context,
opts options, opts options,
clientBuildFS fs.FS, clientBuildFS fs.FS,
upd *updater.Updater, upd *updater.Updater,
baseLogger *slog.Logger, baseLogger *slog.Logger,
tlsMgr *tlsManager,
customURL bool, customURL bool,
) (web *webAPI, err error) { ) (web *webAPI, err error) {
logger := baseLogger.With(slogutil.KeyPrefix, "webapi") logger := baseLogger.With(slogutil.KeyPrefix, "webapi")
@@ -548,6 +555,7 @@ func initWeb(
updater: upd, updater: upd,
logger: logger, logger: logger,
baseLogger: baseLogger, baseLogger: baseLogger,
tlsManager: tlsMgr,
clientFS: clientFS, clientFS: clientFS,
@@ -638,7 +646,7 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}, sigHdlr *signalH
if !globalContext.firstRun { if !globalContext.firstRun {
// Save the updated config. // Save the updated config.
err = config.write() err = config.write(nil)
fatalOnError(err) fatalOnError(err)
if config.HTTPConfig.Pprof.Enabled { if config.HTTPConfig.Pprof.Enabled {
@@ -656,25 +664,26 @@ func run(opts options, clientBuildFS fs.FS, done chan struct{}, sigHdlr *signalH
globalContext.auth, err = initUsers() globalContext.auth, err = initUsers()
fatalOnError(err) fatalOnError(err)
globalContext.tls, err = newTLSManager(config.TLS, config.DNS.ServePlainDNS) tlsMgr, err := newTLSManager(config.TLS, config.DNS.ServePlainDNS)
if err != nil { if err != nil {
log.Error("initializing tls: %s", err) log.Error("initializing tls: %s", err)
onConfigModified() onConfigModified()
} }
sigHdlr.addTLSManager(globalContext.tls) globalContext.tls = tlsMgr
sigHdlr.addTLSManager(tlsMgr)
globalContext.web, err = initWeb(ctx, opts, clientBuildFS, upd, slogLogger, customURL) globalContext.web, err = initWeb(ctx, opts, clientBuildFS, upd, slogLogger, tlsMgr, customURL)
fatalOnError(err) fatalOnError(err)
statsDir, querylogDir, err := checkStatsAndQuerylogDirs(&globalContext, config) statsDir, querylogDir, err := checkStatsAndQuerylogDirs(&globalContext, config)
fatalOnError(err) fatalOnError(err)
if !globalContext.firstRun { if !globalContext.firstRun {
err = initDNS(slogLogger, statsDir, querylogDir) err = initDNS(slogLogger, tlsMgr, statsDir, querylogDir)
fatalOnError(err) fatalOnError(err)
globalContext.tls.start() tlsMgr.start(ctx)
go func() { go func() {
startErr := startDNSServer() startErr := startDNSServer()
@@ -807,31 +816,6 @@ func (c *configuration) anonymizer() (ipmut *aghnet.IPMut) {
return aghnet.NewIPMut(anonFunc) return aghnet.NewIPMut(anonFunc)
} }
// startMods initializes and starts the DNS server after installation.
// baseLogger must not be nil.
func startMods(baseLogger *slog.Logger) (err error) {
statsDir, querylogDir, err := checkStatsAndQuerylogDirs(&globalContext, config)
if err != nil {
return err
}
err = initDNS(baseLogger, statsDir, querylogDir)
if err != nil {
return err
}
globalContext.tls.start()
err = startDNSServer()
if err != nil {
closeDNSServer()
return err
}
return nil
}
// checkNetworkPermissions checks if the current user permissions are enough to // checkNetworkPermissions checks if the current user permissions are enough to
// use the required networking functionality. // use the required networking functionality.
func checkNetworkPermissions() { func checkNetworkPermissions() {
@@ -950,10 +934,6 @@ func cleanup(ctx context.Context) {
log.Error("closing hosts container: %s", err) log.Error("closing hosts container: %s", err)
} }
} }
if globalContext.tls != nil {
globalContext.tls = nil
}
} }
// This function is called before application exits // This function is called before application exits
@@ -1005,10 +985,12 @@ func printWebAddrs(proto, addr string, port uint16) {
// printHTTPAddresses prints the IP addresses which user can use to access the // printHTTPAddresses prints the IP addresses which user can use to access the
// admin interface. proto is either schemeHTTP or schemeHTTPS. // admin interface. proto is either schemeHTTP or schemeHTTPS.
func printHTTPAddresses(proto string) { //
// TODO(s.chzhen): Implement separate functions for HTTP and HTTPS.
func printHTTPAddresses(proto string, tlsMgr *tlsManager) {
tlsConf := tlsConfigSettings{} tlsConf := tlsConfigSettings{}
if globalContext.tls != nil { if tlsMgr != nil {
globalContext.tls.WriteDiskConfig(&tlsConf) tlsMgr.WriteDiskConfig(&tlsConf)
} }
port := config.HTTPConfig.Address.Port() port := config.HTTPConfig.Address.Port()
@@ -1016,7 +998,6 @@ func printHTTPAddresses(proto string) {
port = tlsConf.PortHTTPS port = tlsConf.PortHTTPS
} }
// TODO(e.burkov): Inspect and perhaps merge with the previous condition.
if proto == urlutil.SchemeHTTPS && tlsConf.ServerName != "" { if proto == urlutil.SchemeHTTPS && tlsConf.ServerName != "" {
printWebAddrs(proto, tlsConf.ServerName, tlsConf.PortHTTPS) printWebAddrs(proto, tlsConf.ServerName, tlsConf.PortHTTPS)

View File

@@ -19,10 +19,8 @@ func setupDNSIPs(t testing.TB) {
t.Helper() t.Helper()
prevConfig := config prevConfig := config
prevTLS := globalContext.tls
t.Cleanup(func() { t.Cleanup(func() {
config = prevConfig config = prevConfig
globalContext.tls = prevTLS
}) })
config = &configuration{ config = &configuration{
@@ -31,8 +29,6 @@ func setupDNSIPs(t testing.TB) {
Port: defaultPortDNS, Port: defaultPortDNS,
}, },
} }
globalContext.tls = &tlsManager{}
} }
func TestHandleMobileConfigDoH(t *testing.T) { func TestHandleMobileConfigDoH(t *testing.T) {
@@ -62,11 +58,6 @@ func TestHandleMobileConfigDoH(t *testing.T) {
}) })
t.Run("error_no_host", func(t *testing.T) { t.Run("error_no_host", func(t *testing.T) {
oldTLSConf := globalContext.tls
t.Cleanup(func() { globalContext.tls = oldTLSConf })
globalContext.tls = &tlsManager{conf: tlsConfigSettings{}}
r, err := http.NewRequest(http.MethodGet, "https://example.com:12345/apple/doh.mobileconfig", nil) r, err := http.NewRequest(http.MethodGet, "https://example.com:12345/apple/doh.mobileconfig", nil)
require.NoError(t, err) require.NoError(t, err)
@@ -134,11 +125,6 @@ func TestHandleMobileConfigDoT(t *testing.T) {
}) })
t.Run("error_no_host", func(t *testing.T) { t.Run("error_no_host", func(t *testing.T) {
oldTLSConf := globalContext.tls
t.Cleanup(func() { globalContext.tls = oldTLSConf })
globalContext.tls = &tlsManager{conf: tlsConfigSettings{}}
r, err := http.NewRequest(http.MethodGet, "https://example.com:12345/apple/dot.mobileconfig", nil) r, err := http.NewRequest(http.MethodGet, "https://example.com:12345/apple/dot.mobileconfig", nil)
require.NoError(t, err) require.NoError(t, err)

View File

@@ -339,7 +339,7 @@ AdGuard Home is successfully installed and will automatically start on boot.
There are a few more things that must be configured before you can use it. There are a few more things that must be configured before you can use it.
Click on the link below and follow the Installation Wizard steps to finish setup. Click on the link below and follow the Installation Wizard steps to finish setup.
AdGuard Home is now available at the following addresses:`) AdGuard Home is now available at the following addresses:`)
printHTTPAddresses(urlutil.SchemeHTTP) printHTTPAddresses(urlutil.SchemeHTTP, nil)
} }
} }

View File

@@ -102,7 +102,9 @@ func (m *tlsManager) setCertFileTime() {
} }
// start updates the configuration of t and starts it. // start updates the configuration of t and starts it.
func (m *tlsManager) start() { //
// TODO(s.chzhen): Use context.
func (m *tlsManager) start(_ context.Context) {
m.registerWebHandlers() m.registerWebHandlers()
m.confLock.Lock() m.confLock.Lock()
@@ -151,7 +153,7 @@ func (m *tlsManager) reload() {
m.certLastMod = fi.ModTime().UTC() m.certLastMod = fi.ModTime().UTC()
_ = reconfigureDNSServer() _ = reconfigureDNSServer(m)
m.confLock.Lock() m.confLock.Lock()
tlsConf = m.conf tlsConf = m.conf
@@ -440,7 +442,7 @@ func (m *tlsManager) handleTLSConfigure(w http.ResponseWriter, r *http.Request)
onConfigModified() onConfigModified()
err = reconfigureDNSServer() err = reconfigureDNSServer(m)
if err != nil { if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "%s", err) aghhttp.Error(r, w, http.StatusInternalServerError, "%s", err)

View File

@@ -49,6 +49,10 @@ type webConfig struct {
// nil. // nil.
baseLogger *slog.Logger baseLogger *slog.Logger
// tlsManager contains the current configuration and state of TLS
// encryption. It must not be nil.
tlsManager *tlsManager
clientFS fs.FS clientFS fs.FS
// BindAddr is the binding address with port for plain HTTP web interface. // BindAddr is the binding address with port for plain HTTP web interface.
@@ -108,6 +112,10 @@ type webAPI struct {
// nil. // nil.
baseLogger *slog.Logger baseLogger *slog.Logger
// tlsManager contains the current configuration and state of TLS
// encryption.
tlsManager *tlsManager
// httpsServer is the server that handles HTTPS traffic. If it is not nil, // httpsServer is the server that handles HTTPS traffic. If it is not nil,
// [Web.http3Server] must also not be nil. // [Web.http3Server] must also not be nil.
httpsServer httpsServer httpsServer httpsServer
@@ -124,6 +132,7 @@ func newWebAPI(ctx context.Context, conf *webConfig) (w *webAPI) {
conf: conf, conf: conf,
logger: conf.logger, logger: conf.logger,
baseLogger: conf.baseLogger, baseLogger: conf.baseLogger,
tlsManager: conf.tlsManager,
} }
clientFS := http.FileServer(http.FS(conf.clientFS)) clientFS := http.FileServer(http.FS(conf.clientFS))
@@ -220,7 +229,7 @@ func (web *webAPI) start(ctx context.Context) {
// this loop is used as an ability to change listening host and/or port // this loop is used as an ability to change listening host and/or port
for !web.httpsServer.inShutdown { for !web.httpsServer.inShutdown {
printHTTPAddresses(urlutil.SchemeHTTP) printHTTPAddresses(urlutil.SchemeHTTP, web.tlsManager)
errs := make(chan error, 2) errs := make(chan error, 2)
// Use an h2c handler to support unencrypted HTTP/2, e.g. for proxies. // Use an h2c handler to support unencrypted HTTP/2, e.g. for proxies.
@@ -330,7 +339,7 @@ func (web *webAPI) tlsServerLoop(ctx context.Context) {
ErrorLog: slog.NewLogLogger(logger.Handler(), slog.LevelError), ErrorLog: slog.NewLogLogger(logger.Handler(), slog.LevelError),
} }
printHTTPAddresses(urlutil.SchemeHTTPS) printHTTPAddresses(urlutil.SchemeHTTPS, web.tlsManager)
if web.conf.serveHTTP3 { if web.conf.serveHTTP3 {
go web.mustStartHTTP3(ctx, addr) go web.mustStartHTTP3(ctx, addr)