1

I am trying to redirect the API call to HTTPS if an api call is made to HTTP, But I get an nil in r.URL.Scheme and r.TLS for both HTTP and HTTPS calls

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/info", infoHandler).Methods("GET")   
    portString := fmt.Sprintf(":%s", getPorts())

    if cfenv.IsRunningOnCF() == true {
        r.Use(redirectTLS)
    }

    if err := http.ListenAndServe(portString, r); err != nil {
        panic(err)
    }

}

func redirectTLS(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

        //if r.URL.Scheme != "https" {
        if r.TLS == nil {
            log.Info("Redirecting to HTTPS")
            //targetUrl := url.URL{Scheme: "https", Host: r.Host, Path: r.URL.Path, RawQuery: r.URL.RawQuery}
            http.Redirect(w, r, "https://"+r.Host+r.RequestURI, http.StatusMovedPermanently)
            //http.Redirect(w, r, targetUrl, http.StatusMovedPermanently)
            return
        }

        log.Info("Not Redirecting to HTTPS")
        next.ServeHTTP(w, r)
        return
    })
}
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
MANOJ
  • 716
  • 4
  • 10
  • 29
  • Your listener can't be receiving https requests, because it's not using TLS. The listener that receives the requests should know how it's configured and can redirect appropriately. – JimB Nov 08 '19 at 22:35
  • My suggestion, use nginx for this kind of service. – 7urkm3n Nov 08 '19 at 22:45
  • 1
    If this is for web content that's one thing, but if it's for REST calls - then don't bother doing redirects - just fail with an appropriate error. Redirects for REST are a waste of resources. Clients should know to use https. – colm.anseo Nov 09 '19 at 15:36

1 Answers1

0

If the application is directly serving HTTP and HTTPS, then the application is running two listeners. Configure the handler running on the HTTP listener to redirect to HTTPS. Configure the HTTPS handler as normal:

// Redirect HTTP to HTTPS
go func() {
        log.Fatal(http.ListenAndServe(httpPort, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    http.Redirect(w, r, "https://"+r.Host+r.RequestURI, http.StatusMovedPermanently)
    })))
    }()


// Run the application as normal on HTTPS.
r := mux.NewRouter()
r.HandleFunc("/info", infoHandler).Methods("GET")
log.Fatal(http.ListenAndServeTLS(httpsPport, certFile, keyFile, r))

There is no need to wrap existing handlers with a redirector because HTTP and HTTPS requests to go different handlers.

If the application is running behind a reverse proxy, then configure the proxy to redirect HTTP to HTTPS.