Skip to content

Commit 13ff668

Browse files
committed
not force HTTPS for localhost and private IP ranges
1 parent 2368420 commit 13ff668

1 file changed

Lines changed: 32 additions & 3 deletions

File tree

main.go

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
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+
132161
func isHTTPS(r *http.Request) bool {
133162
if r.TLS != nil {
134163
return true

0 commit comments

Comments
 (0)