github.com/gocaveman/caveman@v0.0.0-20191211162744-0ddf99dbdf6e/webutil/https-redirect-handler.go (about)

     1  package webutil
     2  
     3  import (
     4  	"net"
     5  	"net/http"
     6  )
     7  
     8  // NewHTTPSRedirectHandler creates a new HTTPSRedirectHandler using the defaults.
     9  func NewHTTPSRedirectHandler() *HTTPSRedirectHandler {
    10  	return &HTTPSRedirectHandler{
    11  		IgnorePathPrefixes: DefaultHTTPSIgnorePathPrefixes,
    12  		HTTPSRedirect:      DefaultHTTPS302RedirectHandler,
    13  	}
    14  }
    15  
    16  // DefaultHTTPSIgnorePathPrefixes are paths that we don't want to redirect to HTTPS.
    17  var DefaultHTTPSIgnorePathPrefixes = []string{
    18  	"/.well-known", // path prefix needed for LetsEncrypt support
    19  }
    20  
    21  // HTTPSRedirectHandler will redirect all requests which do not have r.URL.Scheme=="https".
    22  type HTTPSRedirectHandler struct {
    23  	IgnorePathPrefixes []string     // do not HTTPS redirects for these path prefixes
    24  	HTTPSRedirect      http.Handler // the handler to perform the actual redirect to HTTPS
    25  }
    26  
    27  // DefaultHTTPS302RedirectHandler redirects to HTTPS by doing a 302 redirect to https://HOST/PATH
    28  // constructed from the original request, with the port number removed from the host.
    29  var DefaultHTTPS302RedirectHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    30  
    31  	u := *r.URL
    32  	if h, _, err := net.SplitHostPort(r.Host); err == nil {
    33  		u.Host = h
    34  	} else {
    35  		u.Host = r.Host
    36  	}
    37  	u.Scheme = "https"
    38  	http.Redirect(w, r, u.String(), 302)
    39  })
    40  
    41  // DefaultHTTPS301RedirectHandler redirects to HTTPS by doing a 301 redirect to https://HOST/PATH
    42  // constructed from the original request, with the port number removed from the host.
    43  var DefaultHTTPS301RedirectHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    44  
    45  	u := *r.URL
    46  	if h, _, err := net.SplitHostPort(r.Host); err == nil {
    47  		u.Host = h
    48  	} else {
    49  		u.Host = r.Host
    50  	}
    51  	u.Scheme = "https"
    52  	http.Redirect(w, r, u.String(), 302)
    53  })
    54  
    55  func (h *HTTPSRedirectHandler) ServeHTTPChain(w http.ResponseWriter, r *http.Request) (http.ResponseWriter, *http.Request) {
    56  
    57  	if r.URL.Scheme == "https" {
    58  		return w, r
    59  	}
    60  
    61  	for _, v := range h.IgnorePathPrefixes {
    62  		if HasPathPrefix(r.URL.Path, v) {
    63  			return w, r
    64  		}
    65  	}
    66  
    67  	h.HTTPSRedirect.ServeHTTP(w, r)
    68  
    69  	return w, r
    70  }