/install/configure -- Rebind HTTP server when we get new host and port

This commit is contained in:
Eugene Bujak 2019-02-06 16:47:17 +03:00
parent 31b855f9ab
commit 06a28a461d
2 changed files with 23 additions and 4 deletions

15
app.go
View File

@ -20,6 +20,7 @@ import (
// VersionString will be set through ldflags, contains current version // VersionString will be set through ldflags, contains current version
var VersionString = "undefined" var VersionString = "undefined"
var httpServer *http.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
@ -147,10 +148,22 @@ func run(args options) {
http.Handle("/install.html", preInstallHandler(http.FileServer(box))) http.Handle("/install.html", preInstallHandler(http.FileServer(box)))
registerControlHandlers() registerControlHandlers()
// this loop is used as an ability to change listening host and/or port
for {
address := net.JoinHostPort(config.BindHost, strconv.Itoa(config.BindPort)) address := net.JoinHostPort(config.BindHost, strconv.Itoa(config.BindPort))
URL := fmt.Sprintf("http://%s", address) URL := fmt.Sprintf("http://%s", address)
log.Println("Go to " + URL) log.Println("Go to " + URL)
log.Fatal(http.ListenAndServe(address, nil)) // we need to have new instance, because after Shutdown() the Server is not usable
httpServer = &http.Server{
Addr: address,
}
err := httpServer.ListenAndServe()
if err != http.ErrServerClosed {
log.Fatal(err)
os.Exit(1)
}
// We use ErrServerClosed as a sign that we need to rebind on new address, so go back to the start of the loop
}
} }
// initWorkingDir initializes the ourBinaryDir (basically, we use it as a working dir) // initWorkingDir initializes the ourBinaryDir (basically, we use it as a working dir)

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
@ -793,6 +794,11 @@ func handleInstallConfigure(w http.ResponseWriter, r *http.Request) {
} }
httpUpdateConfigReloadDNSReturnOK(w, r) httpUpdateConfigReloadDNSReturnOK(w, r)
// this needs to be done in a goroutine because Shutdown() is a blocking call, and it will block
// until all requests are finished, and _we_ are inside a request right now, so it will block indefinitely
go func() {
httpServer.Shutdown(context.TODO())
}()
} }
func registerControlHandlers() { func registerControlHandlers() {