diff pkg/controllers/json.go @ 4243:d776110b4db0 json-handler-middleware

Made the de-serialized input of the JSON handler accessible via the context of the request.
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 22 Aug 2019 10:54:08 +0200
parents 1458c9b0fdaa
children
line wrap: on
line diff
--- a/pkg/controllers/json.go	Thu Aug 22 10:18:13 2019 +0200
+++ b/pkg/controllers/json.go	Thu Aug 22 10:54:08 2019 +0200
@@ -48,9 +48,7 @@
 	Input func(*http.Request) interface{}
 	// Handle is called to handle the incoming HTTP request.
 	// in is the data structure returned by Input. Its nil if Input is nil.
-	// req is the incoming HTTP request.
-	// conn is the impersonated connection to the database.
-	Handle func(in interface{}, rep *http.Request) (JSONResult, error)
+	Handle func(rep *http.Request) (JSONResult, error)
 	// NoConn if set to true no database connection is established and
 	// the conn parameter of the Handle call is nil.
 	NoConn bool
@@ -77,21 +75,29 @@
 
 type jsonHandlerType int
 
-const jsonDBKey jsonHandlerType = 0
+const (
+	jsonConnKey jsonHandlerType = iota
+	jsonInputKey
+)
 
+// JSONConn extracts the impersonated sql.Conn from the context of the request.
 func JSONConn(req *http.Request) *sql.Conn {
-	if conn, ok := req.Context().Value(jsonDBKey).(*sql.Conn); ok {
+	if conn, ok := req.Context().Value(jsonConnKey).(*sql.Conn); ok {
 		return conn
 	}
 	return nil
 }
 
+// JSONConn extracts the de-serialized input from the context of the request.
+func JSONInput(req *http.Request) interface{} {
+	return req.Context().Value(jsonInputKey)
+}
+
 // ServeHTTP makes the JSONHandler a middleware.
 func (j *JSONHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
 
-	var input interface{}
 	if j.Input != nil {
-		input = j.Input(req)
+		input := j.Input(req)
 		defer req.Body.Close()
 		var r io.Reader
 		switch {
@@ -106,6 +112,9 @@
 			http.Error(rw, "error: "+err.Error(), http.StatusBadRequest)
 			return
 		}
+		parent := req.Context()
+		ctx := context.WithValue(parent, jsonInputKey, input)
+		req = req.WithContext(ctx)
 	}
 
 	var jr JSONResult
@@ -115,16 +124,16 @@
 		if session := auth.Sessions.Session(token); session != nil {
 			parent := req.Context()
 			err = auth.RunAs(parent, session.User, func(conn *sql.Conn) error {
-				ctx := context.WithValue(parent, jsonDBKey, conn)
-				r := req.WithContext(ctx)
-				jr, err = j.Handle(input, r)
+				ctx := context.WithValue(parent, jsonConnKey, conn)
+				req = req.WithContext(ctx)
+				jr, err = j.Handle(req)
 				return err
 			})
 		} else {
 			err = auth.ErrNoSuchToken
 		}
 	} else {
-		jr, err = j.Handle(input, req)
+		jr, err = j.Handle(req)
 	}
 
 	if err != nil {