Ctrl K
ComunidadGuías…

internal/server/tls.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package server

import (
	"fmt"
	"net"
	"net/http"
	"strings"

	"armdash/internal/config"
)

const (
	tlsCertKey = "core.tls_cert"
	tlsKeyKey  = "core.tls_key"
)

// TLSFiles returns the certificate and key paths, both empty when TLS is off.
// One without the other is an error rather than a quiet fall back to HTTP.
func TLSFiles(cfg *config.Config) (cert, key string, err error) {
	cert, key = cfg.Get(tlsCertKey), cfg.Get(tlsKeyKey)
	if (cert == "") != (key == "") {
		return "", "", fmt.Errorf("%s and %s must be set together",
			config.EnvName(tlsCertKey), config.EnvName(tlsKeyKey))
	}
	return cert, key, nil
}

// PlainHandler serves the plain HTTP listener once TLS is on. /metrics stays
// here so Prometheus keeps scraping over loopback without having to trust the
// certificate, everything else is sent to the HTTPS listener at tlsAddr.
//
// There is deliberately no Strict-Transport-Security header: a pin on a LAN
// host name signed by a private CA would lock out every device that does not
// trust that CA.
func (s *Server) PlainHandler(tlsAddr string) http.Handler {
	_, port, err := net.SplitHostPort(tlsAddr)
	if err != nil || port == "" {
		port = "443"
	}
	mux := http.NewServeMux()
	mux.HandleFunc("GET /metrics", func(w http.ResponseWriter, r *http.Request) { s.tree().handleMetrics(w, r) })
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		host := r.Host
		if h, _, err := net.SplitHostPort(host); err == nil {
			host = h
		}
		host = strings.Trim(host, "[]")
		target := strings.TrimSuffix(net.JoinHostPort(host, port), ":443")
		http.Redirect(w, r, "https://"+target+r.URL.RequestURI(), http.StatusMovedPermanently)
	})
	return mux
}