heroku の golang で http から https へリダイレクト

お名前.comで取得した カスタムドメインを使ってhttps化しようと思ったけど、なんか難しかったので、カスタムドメインはあきらめた。んで、herokuapp.com のサブドメインSSL化してhttps化完了とす。

でも、httpのほうもアクセスできちゃうので、そっちをどうにか閉じたい。herokuの機能としてhttpからhttpsへのリダイレクトはサポートされていないようなので、自前でリダイレクトしてあげないといけないっぽい。

Can Heroku force an application to use SSL/TLS? - Heroku Help

でも、↑のサンプルには go のサンプルがない... つらたん...

なので、色んなサイトを参考に以下のように作成。

func main() {
    var err error
    proto := os.Getenv("PROTO")
    if proto == "" {
        proto = "https"
    }

    engine := gin.New()
    engine.Use(func(c *gin.Context) {
        if proto != "https" {
            return
        }

        header := c.Request.Header
        isssl := false
        if params, ok := header["X-Forwarded-Proto"]; ok {
            if len(params) != 0 && params[0] == "https" {
                isssl = true
            }
        }
        if !isssl {
            req := c.Request
            loc := "https://" + req.Host + req.URL.Path
            if len(req.URL.RawQuery) > 0 {
                loc += "?" + req.URL.RawQuery
            }
            c.Redirect(http.StatusMovedPermanently, loc)
        }
    })

    engine.Run(":" + port)
}

抜粋なので、これだけではちゃんと動かない。 全体は こちら

ローカルでは http で動かしたかったので、環境変数PROTOがあるかどうかで判別している。 herokuでは、httpsの場合だと、X-Forwarded-Protohttpsが入ってくるらしいので、それをチェックして httpsじゃない場合はリダイレクトしている。