package main import ( "fmt" "net" "net/http" "os" "strconv" "strings" ) const usage = "servetls " func main() { if len(os.Args) != 3 { fmt.Fprintf(os.Stderr, "%s\n", usage) os.Exit(1) } cert, key := os.Args[1], os.Args[2] http.HandleFunc("/", handler) tlsPort := 8443 if os.Getenv("TLS_PORT") != "" { p, err := strconv.Atoi(os.Getenv("TLS_PORT")) if err != nil { fmt.Fprintf(os.Stderr, "could not parse TLS_PORT variable: %s\n", os.Getenv("TLS_PORT")) os.Exit(1) } tlsPort = p } port := 8000 if os.Getenv("PORT") != "" { p, err := strconv.Atoi(os.Getenv("PORT")) if err != nil { fmt.Fprintf(os.Stderr, "could not parse PORT variable: %s\n", os.Getenv("PORT")) os.Exit(1) } port = p } go func() { b := &bouncer{tlsPort} sm := http.NewServeMux() sm.Handle("/", b) addr := fmt.Sprintf(":%d", port) if err := http.ListenAndServe(addr, sm); err != nil { panic(err) } }() fmt.Printf("redirecting on :%d\n", port) fmt.Printf("serving on :%d\n", tlsPort) addr := fmt.Sprintf(":%d", tlsPort) err := http.ListenAndServeTLS(addr, cert, key, nil) if err != nil { fmt.Fprintf(os.Stderr, "%v\n", err) os.Exit(1) } } func handler(w http.ResponseWriter, req *http.Request) { fmt.Fprintf(w, "if you see this without complaints things are likely set up correctly\n") } type bouncer struct { port int } func (b *bouncer) ServeHTTP(w http.ResponseWriter, req *http.Request) { var host string var err error if strings.Contains(req.Host, ":") { host, _, err = net.SplitHostPort(req.Host) if err != nil { http.Error(w, "couldn't parse hostname from requeest", http.StatusBadRequest) return } } else { host = req.Host } url := fmt.Sprintf("https://%s:%d/", host, b.port) http.Redirect(w, req, url, http.StatusMovedPermanently) }