* move "httpsServer" to "config"

This commit is contained in:
Simon Zolin 2019-07-09 18:50:17 +03:00
parent f79008d9d0
commit 2780ace63e
4 changed files with 28 additions and 25 deletions

View File

@ -39,6 +39,13 @@ type clientObject struct {
SafeBrowsingEnabled bool `yaml:"safesearch_enabled"` SafeBrowsingEnabled bool `yaml:"safesearch_enabled"`
} }
type HTTPSServer struct {
server *http.Server
cond *sync.Cond // reacts to config.TLS.Enabled, PortHTTPS, CertificateChain and PrivateKey
sync.Mutex // protects config.TLS
shutdown bool // if TRUE, don't restart the server
}
// configuration is loaded from YAML // configuration is loaded from YAML
// field ordering is important -- yaml fields will mirror ordering from here // field ordering is important -- yaml fields will mirror ordering from here
type configuration struct { type configuration struct {
@ -63,6 +70,8 @@ type configuration struct {
versionCheckJSON []byte versionCheckJSON []byte
versionCheckLastTime time.Time versionCheckLastTime time.Time
httpsServer HTTPSServer
BindHost string `yaml:"bind_host"` // BindHost is the IP address of the HTTP server to bind to BindHost string `yaml:"bind_host"` // BindHost is the IP address of the HTTP server to bind to
BindPort int `yaml:"bind_port"` // BindPort is the port the HTTP server BindPort int `yaml:"bind_port"` // BindPort is the port the HTTP server
AuthName string `yaml:"auth_name"` // AuthName is the basic auth username AuthName string `yaml:"auth_name"` // AuthName is the basic auth username

View File

@ -46,7 +46,7 @@ func handleTLSValidate(w http.ResponseWriter, r *http.Request) {
// check if port is available // check if port is available
// BUT: if we are already using this port, no need // BUT: if we are already using this port, no need
alreadyRunning := false alreadyRunning := false
if httpsServer.server != nil { if config.httpsServer.server != nil {
alreadyRunning = true alreadyRunning = true
} }
if !alreadyRunning { if !alreadyRunning {
@ -72,7 +72,7 @@ func handleTLSConfigure(w http.ResponseWriter, r *http.Request) {
// check if port is available // check if port is available
// BUT: if we are already using this port, no need // BUT: if we are already using this port, no need
alreadyRunning := false alreadyRunning := false
if httpsServer.server != nil { if config.httpsServer.server != nil {
alreadyRunning = true alreadyRunning = true
} }
if !alreadyRunning { if !alreadyRunning {
@ -101,12 +101,12 @@ func handleTLSConfigure(w http.ResponseWriter, r *http.Request) {
if restartHTTPS { if restartHTTPS {
go func() { go func() {
time.Sleep(time.Second) // TODO: could not find a way to reliably know that data was fully sent to client by https server, so we wait a bit to let response through before closing the server time.Sleep(time.Second) // TODO: could not find a way to reliably know that data was fully sent to client by https server, so we wait a bit to let response through before closing the server
httpsServer.cond.L.Lock() config.httpsServer.cond.L.Lock()
httpsServer.cond.Broadcast() config.httpsServer.cond.Broadcast()
if httpsServer.server != nil { if config.httpsServer.server != nil {
httpsServer.server.Shutdown(context.TODO()) config.httpsServer.server.Shutdown(context.TODO())
} }
httpsServer.cond.L.Unlock() config.httpsServer.cond.L.Unlock()
}() }()
} }
} }

View File

@ -148,7 +148,7 @@ func postInstall(handler func(http.ResponseWriter, *http.Request)) func(http.Res
return return
} }
// enforce https? // enforce https?
if config.TLS.ForceHTTPS && r.TLS == nil && config.TLS.Enabled && config.TLS.PortHTTPS != 0 && httpsServer.server != nil { if config.TLS.ForceHTTPS && r.TLS == nil && config.TLS.Enabled && config.TLS.PortHTTPS != 0 && config.httpsServer.server != nil {
// yes, and we want host from host:port // yes, and we want host from host:port
host, _, err := net.SplitHostPort(r.Host) host, _, err := net.SplitHostPort(r.Host)
if err != nil { if err != nil {

View File

@ -26,12 +26,6 @@ import (
) )
var httpServer *http.Server var httpServer *http.Server
var httpsServer struct {
server *http.Server
cond *sync.Cond // reacts to config.TLS.Enabled, PortHTTPS, CertificateChain and PrivateKey
sync.Mutex // protects config.TLS
shutdown bool // if TRUE, don't restart the server
}
const ( const (
// Used in config to indicate that syslog or eventlog (win) should be used for logger output // Used in config to indicate that syslog or eventlog (win) should be used for logger output
@ -192,13 +186,13 @@ func run(args options) {
registerInstallHandlers() registerInstallHandlers()
} }
httpsServer.cond = sync.NewCond(&httpsServer.Mutex) config.httpsServer.cond = sync.NewCond(&config.httpsServer.Mutex)
// for https, we have a separate goroutine loop // for https, we have a separate goroutine loop
go httpServerLoop() go httpServerLoop()
// 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 !httpsServer.shutdown { for !config.httpsServer.shutdown {
printHTTPAddresses("http") printHTTPAddresses("http")
// we need to have new instance, because after Shutdown() the Server is not usable // we need to have new instance, because after Shutdown() the Server is not usable
@ -219,14 +213,14 @@ func run(args options) {
} }
func httpServerLoop() { func httpServerLoop() {
for !httpsServer.shutdown { for !config.httpsServer.shutdown {
httpsServer.cond.L.Lock() config.httpsServer.cond.L.Lock()
// this mechanism doesn't let us through until all conditions are met // this mechanism doesn't let us through until all conditions are met
for config.TLS.Enabled == false || for config.TLS.Enabled == false ||
config.TLS.PortHTTPS == 0 || config.TLS.PortHTTPS == 0 ||
config.TLS.PrivateKey == "" || config.TLS.PrivateKey == "" ||
config.TLS.CertificateChain == "" { // sleep until necessary data is supplied config.TLS.CertificateChain == "" { // sleep until necessary data is supplied
httpsServer.cond.Wait() config.httpsServer.cond.Wait()
} }
address := net.JoinHostPort(config.BindHost, strconv.Itoa(config.TLS.PortHTTPS)) address := net.JoinHostPort(config.BindHost, strconv.Itoa(config.TLS.PortHTTPS))
// validate current TLS config and update warnings (it could have been loaded from file) // validate current TLS config and update warnings (it could have been loaded from file)
@ -250,10 +244,10 @@ func httpServerLoop() {
cleanupAlways() cleanupAlways()
log.Fatal(err) log.Fatal(err)
} }
httpsServer.cond.L.Unlock() config.httpsServer.cond.L.Unlock()
// prepare HTTPS server // prepare HTTPS server
httpsServer.server = &http.Server{ config.httpsServer.server = &http.Server{
Addr: address, Addr: address,
TLSConfig: &tls.Config{ TLSConfig: &tls.Config{
Certificates: []tls.Certificate{cert}, Certificates: []tls.Certificate{cert},
@ -262,7 +256,7 @@ func httpServerLoop() {
} }
printHTTPAddresses("https") printHTTPAddresses("https")
err = httpsServer.server.ListenAndServeTLS("", "") err = config.httpsServer.server.ListenAndServeTLS("", "")
if err != http.ErrServerClosed { if err != http.ErrServerClosed {
cleanupAlways() cleanupAlways()
log.Fatal(err) log.Fatal(err)
@ -399,9 +393,9 @@ func cleanup() {
// Stop HTTP server, possibly waiting for all active connections to be closed // Stop HTTP server, possibly waiting for all active connections to be closed
func stopHTTPServer() { func stopHTTPServer() {
httpsServer.shutdown = true config.httpsServer.shutdown = true
if httpsServer.server != nil { if config.httpsServer.server != nil {
httpsServer.server.Shutdown(context.TODO()) config.httpsServer.server.Shutdown(context.TODO())
} }
httpServer.Shutdown(context.TODO()) httpServer.Shutdown(context.TODO())
} }