Naming, layout and comments: descriptive full-word names, one item per line in wrapped calls and literals, and doc comments on exported names
Short and single-letter names in application code become full words (tests keep theirs). Wrapped calls, signatures and composite literals put one item per line, and one-line function bodies are expanded. Exported names and groups of constants get doc comments, and comments refer to the renamed identifiers.
This commit is contained in:
1 parent
043e307663
commit
465358609a
78 files changed
+2374
-1402
No files matched your search
@@ -20,8 +20,8 @@ type ClientInfo struct {
|
||||
// Client returns the ClientInfo stored by RealIP. Without RealIP it falls back
|
||||
// to the connection itself (see peerInfo) and ignores forwarding headers.
|
||||
func Client(r *http.Request) ClientInfo {
|
||||
if ci, ok := r.Context().Value(clientInfoKey).(ClientInfo); ok {
|
||||
return ci
|
||||
if info, ok := r.Context().Value(clientInfoKey).(ClientInfo); ok {
|
||||
return info
|
||||
}
|
||||
return peerInfo(r)
|
||||
}
|
||||
@@ -62,10 +62,14 @@ func peerInfo(r *http.Request) ClientInfo {
|
||||
|
||||
// RealIPOptions configures RealIP.
|
||||
type RealIPOptions struct {
|
||||
// Trusted are the proxies whose forwarding headers are believed.
|
||||
Trusted []netip.Prefix
|
||||
// Headers is processed in increasing priority order - the last header in the
|
||||
// list that is found is the header used to determine a client IP address.
|
||||
Headers []string // e.g. X-Forwarded-For, Forwarded, X-Real-IP
|
||||
// Headers are the headers the client IP is read from, in priority order:
|
||||
// the first of them that the request has and that gives an address is
|
||||
// used. E.g. X-Forwarded-For, Forwarded, X-Real-IP.
|
||||
Headers []string
|
||||
// StripUntrusted removes the forwarding headers from requests that are
|
||||
// not from a trusted proxy.
|
||||
StripUntrusted bool
|
||||
}
|
||||
|
||||
@@ -91,9 +95,9 @@ var forwardingHeaders = []string{
|
||||
// PROXY protocol is handled at the listener (see server package), so by the
|
||||
// time this runs r.RemoteAddr already holds the address from the PROXY header.
|
||||
func RealIP(opts RealIPOptions) func(http.Handler) http.Handler {
|
||||
trusted := func(a netip.Addr) bool {
|
||||
for _, p := range opts.Trusted {
|
||||
if p.Contains(a) {
|
||||
trusted := func(addr netip.Addr) bool {
|
||||
for _, prefix := range opts.Trusted {
|
||||
if prefix.Contains(addr) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -105,19 +109,19 @@ func RealIP(opts RealIPOptions) func(http.Handler) http.Handler {
|
||||
info := peerInfo(r)
|
||||
|
||||
if info.Peer.IsValid() && trusted(info.Peer) {
|
||||
for _, h := range opts.Headers {
|
||||
if ip, ok := clientFromHeader(r.Header, h, trusted); ok {
|
||||
for _, name := range opts.Headers {
|
||||
if ip, ok := clientFromHeader(r.Header, name, trusted); ok {
|
||||
info.IP = ip
|
||||
info.ViaProxy = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if p := forwardedProto(r.Header); p == "http" || p == "https" {
|
||||
info.Scheme = p
|
||||
if proto := forwardedProto(r.Header); proto == "http" || proto == "https" {
|
||||
info.Scheme = proto
|
||||
}
|
||||
} else if opts.StripUntrusted {
|
||||
for _, h := range forwardingHeaders {
|
||||
r.Header.Del(h)
|
||||
for _, name := range forwardingHeaders {
|
||||
r.Header.Del(name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,17 +132,17 @@ func RealIP(opts RealIPOptions) func(http.Handler) http.Handler {
|
||||
}
|
||||
|
||||
func clientFromHeader(
|
||||
h http.Header, name string, trusted func(netip.Addr) bool,
|
||||
header http.Header, name string, trusted func(netip.Addr) bool,
|
||||
) (netip.Addr, bool) {
|
||||
switch http.CanonicalHeaderKey(name) {
|
||||
case "X-Forwarded-For":
|
||||
return walkChain(splitList(h.Values("X-Forwarded-For")), trusted)
|
||||
return walkChain(splitList(header.Values("X-Forwarded-For")), trusted)
|
||||
|
||||
case "Forwarded":
|
||||
var chain []string
|
||||
for _, el := range splitList(h.Values("Forwarded")) {
|
||||
if v, ok := forwardedParam(el, "for"); ok {
|
||||
chain = append(chain, v)
|
||||
for _, element := range splitList(header.Values("Forwarded")) {
|
||||
if value, ok := forwardedParam(element, "for"); ok {
|
||||
chain = append(chain, value)
|
||||
} else {
|
||||
chain = append(chain, "") // element without for= breaks the chain
|
||||
}
|
||||
@@ -146,8 +150,8 @@ func clientFromHeader(
|
||||
return walkChain(chain, trusted)
|
||||
|
||||
case "X-Real-Ip":
|
||||
if v := strings.TrimSpace(h.Get("X-Real-IP")); v != "" {
|
||||
return parseIPToken(v)
|
||||
if value := strings.TrimSpace(header.Get("X-Real-IP")); value != "" {
|
||||
return parseIPToken(value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,15 +178,15 @@ func walkChain(
|
||||
return last, last.IsValid()
|
||||
}
|
||||
|
||||
func forwardedProto(h http.Header) string {
|
||||
if v := h.Get("X-Forwarded-Proto"); v != "" {
|
||||
first, _, _ := strings.Cut(v, ",")
|
||||
func forwardedProto(header http.Header) string {
|
||||
if value := header.Get("X-Forwarded-Proto"); value != "" {
|
||||
first, _, _ := strings.Cut(value, ",")
|
||||
return strings.ToLower(strings.TrimSpace(first))
|
||||
}
|
||||
|
||||
if els := splitList(h.Values("Forwarded")); len(els) > 0 {
|
||||
if v, ok := forwardedParam(els[0], "proto"); ok {
|
||||
return strings.ToLower(v)
|
||||
if elements := splitList(header.Values("Forwarded")); len(elements) > 0 {
|
||||
if value, ok := forwardedParam(elements[0], "proto"); ok {
|
||||
return strings.ToLower(value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,9 +197,9 @@ func forwardedProto(h http.Header) string {
|
||||
// element (RFC 7239).
|
||||
func forwardedParam(element, key string) (string, bool) {
|
||||
for _, pair := range strings.Split(element, ";") {
|
||||
k, v, ok := strings.Cut(strings.TrimSpace(pair), "=")
|
||||
if ok && strings.EqualFold(k, key) {
|
||||
return strings.Trim(strings.TrimSpace(v), `"`), true
|
||||
name, value, ok := strings.Cut(strings.TrimSpace(pair), "=")
|
||||
if ok && strings.EqualFold(name, key) {
|
||||
return strings.Trim(strings.TrimSpace(value), `"`), true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
@@ -203,8 +207,8 @@ func forwardedParam(element, key string) (string, bool) {
|
||||
|
||||
func splitList(values []string) []string {
|
||||
var out []string
|
||||
for _, v := range values {
|
||||
for _, part := range strings.Split(v, ",") {
|
||||
for _, value := range values {
|
||||
for _, part := range strings.Split(value, ",") {
|
||||
if part = strings.TrimSpace(part); part != "" {
|
||||
out = append(out, part)
|
||||
}
|
||||
@@ -214,23 +218,23 @@ func splitList(values []string) []string {
|
||||
}
|
||||
|
||||
// parseIPToken accepts "1.2.3.4", "1.2.3.4:80", "::1", "[::1]" and "[::1]:80".
|
||||
func parseIPToken(s string) (netip.Addr, bool) {
|
||||
s = strings.Trim(strings.TrimSpace(s), `"`)
|
||||
if ap, err := netip.ParseAddrPort(s); err == nil {
|
||||
return ap.Addr().Unmap(), true
|
||||
func parseIPToken(token string) (netip.Addr, bool) {
|
||||
token = strings.Trim(strings.TrimSpace(token), `"`)
|
||||
if addrPort, err := netip.ParseAddrPort(token); err == nil {
|
||||
return addrPort.Addr().Unmap(), true
|
||||
}
|
||||
|
||||
s = strings.TrimSuffix(strings.TrimPrefix(s, "["), "]")
|
||||
if a, err := netip.ParseAddr(s); err == nil {
|
||||
return a.Unmap().WithZone(""), true
|
||||
token = strings.TrimSuffix(strings.TrimPrefix(token, "["), "]")
|
||||
if addr, err := netip.ParseAddr(token); err == nil {
|
||||
return addr.Unmap().WithZone(""), true
|
||||
}
|
||||
|
||||
return netip.Addr{}, false
|
||||
}
|
||||
|
||||
func addrFromRemote(remote string) netip.Addr {
|
||||
if a, ok := parseIPToken(remote); ok {
|
||||
return a
|
||||
if addr, ok := parseIPToken(remote); ok {
|
||||
return addr
|
||||
}
|
||||
return netip.Addr{}
|
||||
}
|
||||
Reference in new issue
Block a user