summaryrefslogtreecommitdiff
path: root/middleware.go
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2025-09-06 15:36:36 -0500
committerJeff Carr <[email protected]>2025-09-06 16:04:51 -0500
commit0d1f53afee67293e930d9f67bd71442c154d196a (patch)
tree6d7d559e27aea94c1b746be9d3e3f4965bebc598 /middleware.go
parentd795dbeb610a8b0aa315e39175f574dd5ee0cc4e (diff)
all kindsa crazy. this needs massive cleanup
Diffstat (limited to 'middleware.go')
-rw-r--r--middleware.go77
1 files changed, 77 insertions, 0 deletions
diff --git a/middleware.go b/middleware.go
new file mode 100644
index 0000000..803e162
--- /dev/null
+++ b/middleware.go
@@ -0,0 +1,77 @@
+package main
+
+import (
+ "bytes"
+ "context"
+ "io/ioutil"
+ "log"
+ "net/http"
+)
+
+// Define a key type to avoid context key collisions.
+type contextKey string
+
+const bufferedBodyKey = contextKey("bufferedBody")
+
+// bufferBodyMiddleware reads the request body and replaces it with a new reader,
+// allowing it to be read multiple times. The original body is stored in the request context.
+func bufferBodyMiddleware(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ // Only buffer if there's a body to read.
+ if r.Body == nil || r.ContentLength == 0 {
+ next.ServeHTTP(w, r)
+ return
+ }
+
+ bodyBytes, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ log.Printf("Error reading body in middleware: %v\n", err)
+ return
+ }
+ defer r.Body.Close()
+
+ // Store the buffered body in the context for downstream handlers.
+ ctx := context.WithValue(r.Context(), bufferedBodyKey, bodyBytes)
+
+ // Replace the original body with a new reader on the buffered bytes.
+ // This allows subsequent handlers to read the body again.
+ r.Body = ioutil.NopCloser(bytes.NewReader(bodyBytes))
+
+ // Call the next handler in the chain with the modified request.
+ next.ServeHTTP(w, r.WithContext(ctx))
+ })
+}
+
+/*
+// okHandler is the final handler. It can now safely access the body from the context,
+// knowing that other middleware might have also read it.
+func okHandler(w http.ResponseWriter, r *http.Request) {
+ // For demonstration, we can try reading the body directly here too.
+ // The middleware ensures this is a fresh stream of the buffered data.
+ bodyFromStream, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ log.Printf("Error reading body in handler: %v", err)
+ http.Error(w, "Internal Server Error", http.StatusInternalServerError)
+ return
+ }
+
+ log.Printf("Handler read %d bytes from the request body stream.", len(bodyFromStream))
+
+ // We can also retrieve the body from the context if needed.
+ bodyFromContext, ok := r.Context().Value(bufferedBodyKey).([]byte)
+ if !ok {
+ log.Println("Could not retrieve buffered body from context.")
+ http.Error(w, "Internal Server Error", http.StatusInternalServerError)
+ return
+ }
+
+ log.Printf("Handler retrieved %d bytes from context.", len(bodyFromContext))
+
+ // Prove they are the same.
+ if !bytes.Equal(bodyFromStream, bodyFromContext) {
+ log.Println("FATAL: Body from stream and context do not match!")
+ }
+
+ fmt.Fprintf(w, "Successfully read body of %d bytes.\n", len(bodyFromContext))
+}
+*/