99 "io"
1010 "log"
1111 mathrand "math/rand"
12+ "net"
1213 "net/http"
1314 "os"
1415 "strings"
@@ -104,10 +105,10 @@ func main() {
104105 mux := http .DefaultServeMux
105106
106107 // forceHTTPS redirects HTTP -> HTTPS for non-local requests using a 301.
107- // We intentionally allow localhost/127.0.0.1 to remain on HTTP for local dev.
108+ // We intentionally allow localhost and private/local IP ranges to remain on HTTP for local dev.
108109 forceHTTPS := func (next http.Handler ) http.Handler {
109110 return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
110- if ! isHTTPS (r ) && ! strings . HasPrefix (r .Host , "localhost" ) && ! strings . HasPrefix ( r . Host , "127.0.0.1" ) {
111+ if ! isHTTPS (r ) && ! isLocalHost (r .Host ) {
111112 // Redirect to the canonical page directly to avoid an intermediate root redirect.
112113 destination := "https://" + r .Host + r .URL .RequestURI ()
113114 if r .URL .Path == "/" {
@@ -117,7 +118,7 @@ func main() {
117118 return
118119 }
119120 // Add HSTS header for secure responses to enforce HTTPS
120- if isHTTPS (r ) && ! strings . HasPrefix (r .Host , "localhost" ) && ! strings . HasPrefix ( r . Host , "127.0.0.1" ) {
121+ if isHTTPS (r ) && ! isLocalHost (r .Host ) {
121122 w .Header ().Set ("Strict-Transport-Security" , "max-age=63072000; includeSubDomains; preload" )
122123 }
123124 next .ServeHTTP (w , r )
@@ -129,6 +130,34 @@ func main() {
129130 log .Fatal (http .ListenAndServe (":" + port , handler ))
130131}
131132
133+ // isLocalHost returns true for localhost, loopback and common private IP ranges.
134+ func isLocalHost (hostport string ) bool {
135+ host := hostport
136+ if h , _ , err := net .SplitHostPort (hostport ); err == nil {
137+ host = h
138+ }
139+ host = strings .ToLower (host )
140+ if host == "localhost" {
141+ return true
142+ }
143+ ip := net .ParseIP (host )
144+ if ip == nil {
145+ return false
146+ }
147+ if ip .IsLoopback () {
148+ return true
149+ }
150+ // Check common private and local ranges using CIDRs
151+ cidrs := []string {"10.0.0.0/8" , "172.16.0.0/12" , "192.168.0.0/16" , "fc00::/7" , "fe80::/10" }
152+ for _ , c := range cidrs {
153+ _ , netw , _ := net .ParseCIDR (c )
154+ if netw != nil && netw .Contains (ip ) {
155+ return true
156+ }
157+ }
158+ return false
159+ }
160+
132161func isHTTPS (r * http.Request ) bool {
133162 if r .TLS != nil {
134163 return true
0 commit comments