host.go (1823B)
1 package v4 2 3 import ( 4 "net/http" 5 "strings" 6 ) 7 8 // SanitizeHostForHeader removes default port from host and updates request.Host 9 func SanitizeHostForHeader(r *http.Request) { 10 host := getHost(r) 11 port := portOnly(host) 12 if port != "" && isDefaultPort(r.URL.Scheme, port) { 13 r.Host = stripPort(host) 14 } 15 } 16 17 // Returns host from request 18 func getHost(r *http.Request) string { 19 if r.Host != "" { 20 return r.Host 21 } 22 23 return r.URL.Host 24 } 25 26 // Hostname returns u.Host, without any port number. 27 // 28 // If Host is an IPv6 literal with a port number, Hostname returns the 29 // IPv6 literal without the square brackets. IPv6 literals may include 30 // a zone identifier. 31 // 32 // Copied from the Go 1.8 standard library (net/url) 33 func stripPort(hostport string) string { 34 colon := strings.IndexByte(hostport, ':') 35 if colon == -1 { 36 return hostport 37 } 38 if i := strings.IndexByte(hostport, ']'); i != -1 { 39 return strings.TrimPrefix(hostport[:i], "[") 40 } 41 return hostport[:colon] 42 } 43 44 // Port returns the port part of u.Host, without the leading colon. 45 // If u.Host doesn't contain a port, Port returns an empty string. 46 // 47 // Copied from the Go 1.8 standard library (net/url) 48 func portOnly(hostport string) string { 49 colon := strings.IndexByte(hostport, ':') 50 if colon == -1 { 51 return "" 52 } 53 if i := strings.Index(hostport, "]:"); i != -1 { 54 return hostport[i+len("]:"):] 55 } 56 if strings.Contains(hostport, "]") { 57 return "" 58 } 59 return hostport[colon+len(":"):] 60 } 61 62 // Returns true if the specified URI is using the standard port 63 // (i.e. port 80 for HTTP URIs or 443 for HTTPS URIs) 64 func isDefaultPort(scheme, port string) bool { 65 if port == "" { 66 return true 67 } 68 69 lowerCaseScheme := strings.ToLower(scheme) 70 if (lowerCaseScheme == "http" && port == "80") || (lowerCaseScheme == "https" && port == "443") { 71 return true 72 } 73 74 return false 75 }