diff options
author | Lauris BH <lauris@nix.lv> | 2021-03-16 00:27:28 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-16 00:27:28 +0200 |
commit | 044cd4d016196e8c7091eee90b7e6f230bba142f (patch) | |
tree | 35f060380813f99588966339c5ddf796a8b8c451 /vendor/github.com/chi-middleware/proxy/middleware.go | |
parent | 6e423d5573c20b78d6e21cb044e8f4d5de5b288a (diff) | |
download | gitea-044cd4d016196e8c7091eee90b7e6f230bba142f.tar.gz gitea-044cd4d016196e8c7091eee90b7e6f230bba142f.zip |
Add reverse proxy configuration support for remote IP address (#14959)
* Add reverse proxy configuration support for remote IP address validation
* Trust all IP addresses in containerized environments by default
* Use single option to specify networks and proxy IP addresses. By default trust all loopback IPs
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Diffstat (limited to 'vendor/github.com/chi-middleware/proxy/middleware.go')
-rw-r--r-- | vendor/github.com/chi-middleware/proxy/middleware.go | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/vendor/github.com/chi-middleware/proxy/middleware.go b/vendor/github.com/chi-middleware/proxy/middleware.go new file mode 100644 index 0000000000..9315e2e023 --- /dev/null +++ b/vendor/github.com/chi-middleware/proxy/middleware.go @@ -0,0 +1,77 @@ +// Copyright 2020 Lauris BH. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package proxy + +// Ported from Goji's middleware, source: +// https://github.com/zenazn/goji/tree/master/web/middleware + +import ( + "net" + "net/http" + "strings" +) + +var xForwardedFor = http.CanonicalHeaderKey("X-Forwarded-For") +var xRealIP = http.CanonicalHeaderKey("X-Real-IP") + +// ForwardedHeaders is a middleware that sets a http.Request's RemoteAddr to the results +// of parsing either the X-Real-IP header or the X-Forwarded-For header (in that +// order). +func ForwardedHeaders(options ...*ForwardedHeadersOptions) func(h http.Handler) http.Handler { + opt := defaultOptions + if len(options) > 0 { + opt = options[0] + } + return func(h http.Handler) http.Handler { + fn := func(w http.ResponseWriter, r *http.Request) { + // Treat unix socket as 127.0.0.1 + if r.RemoteAddr == "@" { + r.RemoteAddr = "127.0.0.1:0" + } + if rip := realIP(r, opt); len(rip) > 0 { + r.RemoteAddr = net.JoinHostPort(rip, "0") + } + + h.ServeHTTP(w, r) + } + + return http.HandlerFunc(fn) + } +} + +func realIP(r *http.Request, options *ForwardedHeadersOptions) string { + host, _, err := net.SplitHostPort(r.RemoteAddr) + if err != nil { + return "" + } + + if !options.isTrustedProxy(net.ParseIP(host)) { + return "" + } + + var ip string + + if xrip := r.Header.Get(xRealIP); xrip != "" { + ip = xrip + } else if xff := r.Header.Get(xForwardedFor); xff != "" { + p := 0 + for i := options.ForwardLimit; i > 0; i-- { + if p > 0 { + xff = xff[:p-2] + } + p = strings.LastIndex(xff, ", ") + if p < 0 { + p = 0 + break + } else { + p += 2 + } + } + + ip = xff[p:] + } + + return ip +} |