summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/chi-middleware/proxy/middleware.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/chi-middleware/proxy/middleware.go')
-rw-r--r--vendor/github.com/chi-middleware/proxy/middleware.go77
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
+}