首页 文章

如何在Go中重写/重定向从http到https?

提问于
浏览
13

我已经提出TLS并且它有效 . 我知道如何在nginx中从http重写为https,但我不再使用nginx了 . 我不知道如何在Go中正确地做到这一点 .

func main() {

    certificate := "/srv/ssl/ssl-bundle.crt"
    privateKey := "/srv/ssl/mykey.key"

    http.HandleFunc("/", rootHander)
    // log.Fatal(http.ListenAndServe(":80", nil))
    log.Fatal(http.ListenAndServeTLS(":443", certificate, privateKey, nil))
}

func rootHander(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("To the moon!"))
}

我怎么能以这种方式做到这一点?

3 回答

  • 12

    创建一个处理重定向到https的处理程序,如:

    func redirectTLS(w http.ResponseWriter, r *http.Request) {
        http.Redirect(w, r, "https://IPAddr:443"+r.RequestURI, http.StatusMovedPermanently)
    }
    

    然后重定向http流量:

    go func() {
        if err := http.ListenAndServe(":80", http.HandlerFunc(redirectTLS)); err != nil {
            log.Fatalf("ListenAndServe error: %v", err)
        }
    }()
    
  • 3
    Package main
    import (
        "fmt"
        "net/http"
    )
    func redirectToHttps(w http.ResponseWriter, r *http.Request) {
        // Redirect the incoming HTTP request. Note that "127.0.0.1:443" will only work if you are accessing the server from your local machine.
        http.Redirect(w, r, "https://127.0.0.1:443"+r.RequestURI, http.StatusMovedPermanently)
    }
    func handler(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hi there!")
        fmt.Println(r.RequestURI)
    }
    func main() {
        http.HandleFunc("/", handler)
        // Start the HTTPS server in a goroutine
        go http.ListenAndServeTLS(":443", "cert.pem", "key.pem", nil)
        // Start the HTTP server and redirect all incoming connections to HTTPS
        http.ListenAndServe(":8080", http.HandlerFunc(redirectToHttps))
    }
    
  • 0

    上面发布的解决方案有点不灵活,特别是如果外部主机名与本地主机不同 .

    这是我用于HTTP-> HTTPS重定向的代码:

    package main
    
    import (
        "net"
        "log"
        "net/http"
    )
    
    var httpAddr ":8080"
    var httpsAddr ":8443"
    
    func main() {
        srv := http.Server{
            Addr: httpsAddr,
        }
    
        _, tlsPort, err := net.SplitHostPort(httpsAddr)
        if err != nil {
            return err
        }
        go redirectToHTTPS(tlsPort)
    
        srv.ListenAndServeTLS("cert.pem", "key.pem")
    }
    
    func redirectToHTTPS(tlsPort string) {
        httpSrv := http.Server{
            Addr: httpAddr,
            Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){
                host, _, _ := net.SplitHostPort(r.Host)
                u := r.URL
                u.Host = net.JoinHostPort(host, tlsPort)
                u.Scheme="https"
                log.Println(u.String())
                http.Redirect(w,r,u.String(), http.StatusMovedPermanently)
            }),
        }
        log.Println(httpSrv.ListenAndServe())
    }
    

    如果您使用标准端口(80,443),则不需要拆分地址的连接,只需在URL上设置方案就足够了 .

相关问题