Skip to content

Instantly share code, notes, and snippets.

@d-schmidt
Last active March 12, 2024 08:04
Show Gist options
  • Save d-schmidt/587ceec34ce1334a5e60 to your computer and use it in GitHub Desktop.
Save d-schmidt/587ceec34ce1334a5e60 to your computer and use it in GitHub Desktop.
How to redirect HTTP to HTTPS with a golang webserver.
package main
import (
"net/http"
"log"
)
func redirect(w http.ResponseWriter, req *http.Request) {
// remove/add not default ports from req.Host
target := "https://" + req.Host + req.URL.Path
if len(req.URL.RawQuery) > 0 {
target += "?" + req.URL.RawQuery
}
log.Printf("redirect to: %s", target)
http.Redirect(w, req, target,
// see comments below and consider the codes 308, 302, or 301
http.StatusTemporaryRedirect)
}
func index(w http.ResponseWriter, req *http.Request) {
// all calls to unknown url paths should return 404
if req.URL.Path != "/" {
log.Printf("404: %s", req.URL.String())
http.NotFound(w, req)
return
}
http.ServeFile(w, req, "index.html")
}
func main() {
// redirect every http request to https
go http.ListenAndServe(":80", http.HandlerFunc(redirect))
// serve index (and anything else) as https
mux := http.NewServeMux()
mux.HandleFunc("/", index)
http.ListenAndServeTLS(":443", "cert.pem", "key.pem", mux)
}
@MakotoE
Copy link

MakotoE commented Aug 15, 2019

Shouldn't you use http.StatusPermanentRedirect (308) as the status code for redirect, not http.StatusTemporaryRedirect (307), because you're probably not going to create an unsecure http route in the future?

@d-schmidt
Copy link
Author

d-schmidt commented Aug 18, 2019

@MakotoE you are probably right. I will add a another comment

@pystub
Copy link

pystub commented Nov 29, 2021

@drstearns it flops on ipv6 addresses.

This is what I came up with:

d := r.Host
if m, _ := regexp.MatchString(`:\d+$`, d); m {
	d = d[:strings.LastIndexByte(d, ':')]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment