feat: Spawn another HTTP server for HTTPS upgrades
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
PapaTutuWawa 2024-01-11 16:32:28 +01:00
parent de14a0e68d
commit 2cbe46dc1a
2 changed files with 70 additions and 4 deletions

View File

@ -8,6 +8,7 @@ import (
"net/http"
"os"
"strings"
"sync"
"time"
"git.polynom.me/rio/internal/acme"
@ -91,6 +92,22 @@ func Handler(pagesDomain, giteaUrl, defaultCsp string, giteaClient *repo.GiteaCl
}
}
// Handle HTTP redirects to HTTPS.
func httpHandler() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Server", "rio")
w.Header().Set("Strict-Transport-Security", "max-age=31536000")
// Upgrade the URL
req.URL.Scheme = "https"
req.URL.Host = req.Host
w.Header().Set("Location", req.URL.String())
// Send the 301
w.WriteHeader(301)
}
}
func runServer(ctx *cli.Context) error {
giteaUrl := ctx.String("gitea-url")
domain := ctx.String("pages-domain")
@ -131,6 +148,16 @@ func runServer(ctx *cli.Context) error {
return err
}
// Listen on the HTTP port
httpAddr := ctx.String("http-host") + ":" + ctx.String("http-port")
httpListener, err := net.Listen("tcp", httpAddr)
if err != nil {
fmt.Println(
fmt.Errorf("Failed to create HTTP listener: %v", err),
)
return err
}
if !acmeDisable {
if acmeEmail == "" || acmeFile == "" || certsFile == "" || acmeDnsProvider == "" {
return errors.New("The options acme-dns-provider, acme-file, acme-email, and certs-file are required")
@ -189,11 +216,38 @@ func runServer(ctx *cli.Context) error {
listener = tls.NewListener(listener, tlsConfig)
}
if err := http.Serve(listener, Handler(domain, giteaUrl, defaultCsp, &giteaClient)); err != nil {
fmt.Printf("Listening failed")
return err
var waitGroup sync.WaitGroup
servers := 2
if acmeDisable {
servers = 1
}
waitGroup.Add(servers)
go func() {
defer waitGroup.Done()
log.Debug("Listening on main HTTP server")
if err := http.Serve(listener, Handler(domain, giteaUrl, defaultCsp, &giteaClient)); err != nil {
log.Fatal(fmt.Errorf("Listening failed: %v", err))
}
log.Debug("Listening on main HTTP server done!")
}()
if !acmeDisable {
go func() {
defer waitGroup.Done()
log.Debug("Listening on redirect HTTP server")
if err := http.Serve(httpListener, httpHandler()); err != nil {
log.Fatal(fmt.Errorf("Listening failed: %v", err))
}
log.Debug("Listening on redirect HTTP server done!")
}()
}
log.Debug("Waiting...")
waitGroup.Wait()
log.Debug("Done...")
return nil
}
@ -219,6 +273,18 @@ func main() {
EnvVars: []string{"PORT"},
Value: "8888",
},
&cli.StringFlag{
Name: "http-host",
Usage: "The host to have unencrypted HTTP listen on",
EnvVars: []string{"HTTP_HOST"},
Value: "127.0.0.1",
},
&cli.StringFlag{
Name: "http-port",
Usage: "The port to have unencrypted HTTP listen on",
EnvVars: []string{"HTTP_PORT"},
Value: "9999",
},
&cli.StringFlag{
Name: "acme-dns-provider",
Usage: "The provider to use for DNS01 challenge solving",