about summary refs log tree commit diff stats
path: root/ctx.go
diff options
context:
space:
mode:
authorBen Morrison <ben@gbmor.dev>2020-05-05 23:43:03 -0400
committerBen Morrison <ben@gbmor.dev>2020-05-05 23:43:03 -0400
commita3c1e1c95798046f72e990412d7342789f047f22 (patch)
treef8e8dd11e10851fab92e48b9d3440deee2c58714 /ctx.go
parent2e43f76937240083033be0357e7cf25b234a7ce0 (diff)
downloadapi-a3c1e1c95798046f72e990412d7342789f047f22.tar.gz
stubbing out the HTTP server
Right now it won't do much. Working on parsing the request
and routing it to the right place.
Diffstat (limited to 'ctx.go')
-rw-r--r--ctx.go55
1 files changed, 55 insertions, 0 deletions
diff --git a/ctx.go b/ctx.go
new file mode 100644
index 0000000..be4fb9b
--- /dev/null
+++ b/ctx.go
@@ -0,0 +1,55 @@
+package main
+
+import (
+	"context"
+	"log"
+	"net"
+	"net/http"
+	"strings"
+)
+
+type ipCtxKey int
+
+const ctxKey ipCtxKey = iota
+
+// Creates a new context containing the request's originating IP.
+// Preference: X-Forwarded-For, X-Real-IP, RemoteAddress
+func newCtxUserIP(ctx context.Context, r *http.Request) context.Context {
+	split := strings.Split(r.RemoteAddr, ":")
+	uip := split[0]
+
+	xFwdFor := http.CanonicalHeaderKey("X-Forwarded-For")
+	if _, ok := r.Header[xFwdFor]; ok {
+		fwdaddr := r.Header[xFwdFor]
+		split := strings.Split(fwdaddr[len(fwdaddr)-1], ":")
+		uip = split[0]
+
+		return context.WithValue(ctx, ctxKey, uip)
+	}
+
+	xRealIP := http.CanonicalHeaderKey("X-Real-IP")
+	if _, ok := r.Header[xRealIP]; ok {
+		realip := r.Header[xRealIP]
+		split := strings.Split(realip[len(realip)-1], ":")
+		uip = split[0]
+	}
+
+	return context.WithValue(ctx, ctxKey, uip)
+}
+
+// Yoinks the IP address from the request's context
+func getIPFromCtx(ctx context.Context) net.IP {
+	uip, ok := ctx.Value(ctxKey).(string)
+	if !ok {
+		log.Printf("Couldn't retrieve IP From Request\n")
+	}
+	return net.ParseIP(uip)
+}
+
+// Middleware to yeet the remote IP address into the request struct
+func ipMiddleware(hop http.Handler) http.Handler {
+	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		ctx := newCtxUserIP(r.Context(), r)
+		hop.ServeHTTP(w, r.WithContext(ctx))
+	})
+}