You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by mi...@apache.org on 2019/04/04 19:14:16 UTC

[trafficcontrol] branch master updated: Fix interface ptr problem (#3394)

This is an automated email from the ASF dual-hosted git repository.

mitchell852 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new 9f65f9f  Fix interface ptr problem (#3394)
9f65f9f is described below

commit 9f65f9feecab83d2b4572eba7e85c729f858b1d0
Author: Matthew Allen Moltzau <Ma...@comcast.com>
AuthorDate: Thu Apr 4 13:14:10 2019 -0600

    Fix interface ptr problem (#3394)
    
    * Fix interface ptr problem
    
    Fixes #3378
    Fixes #3373
    
    Fixes potentially other bugs that would have used the last posted data
    in the handler.
    
    * Copying from the object instead
---
 .../traffic_ops_golang/api/shared_handlers.go      | 41 +++++++++++++++++++---
 1 file changed, 37 insertions(+), 4 deletions(-)

diff --git a/traffic_ops/traffic_ops_golang/api/shared_handlers.go b/traffic_ops/traffic_ops_golang/api/shared_handlers.go
index f3a55e9..94ec67a 100644
--- a/traffic_ops/traffic_ops_golang/api/shared_handlers.go
+++ b/traffic_ops/traffic_ops_golang/api/shared_handlers.go
@@ -25,6 +25,7 @@ import (
 	"errors"
 	"fmt"
 	"net/http"
+	"reflect"
 	"strconv"
 	"strings"
 
@@ -116,7 +117,7 @@ func decodeAndValidateRequestBody(r *http.Request, v Validator) error {
 //      combines the path and query parameters
 //      produces the proper status code based on the error code returned
 //      marshals the structs returned into the proper response json
-func ReadHandler(obj Reader) http.HandlerFunc {
+func ReadHandler(reader Reader) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 		inf, userErr, sysErr, errCode := NewInfo(r, nil, nil)
 		if userErr != nil || sysErr != nil {
@@ -125,7 +126,15 @@ func ReadHandler(obj Reader) http.HandlerFunc {
 		}
 		defer inf.Close()
 
+		interfacePtr := reflect.ValueOf(reader)
+		if interfacePtr.Kind() != reflect.Ptr {
+			HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("reflect: can only indirect from a pointer"))
+			return
+		}
+		objectType := reflect.Indirect(interfacePtr).Type()
+		obj := reflect.New(objectType).Interface().(Reader)
 		obj.SetInfo(inf)
+
 		results, userErr, sysErr, errCode := obj.Read()
 		if userErr != nil || sysErr != nil {
 			HandleErr(w, r, inf.Tx.Tx, errCode, userErr, sysErr)
@@ -142,7 +151,7 @@ func ReadHandler(obj Reader) http.HandlerFunc {
 //   *decoding and validating the struct
 //   *change log entry
 //   *forming and writing the body over the wire
-func UpdateHandler(obj Updater) http.HandlerFunc {
+func UpdateHandler(updater Updater) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 		inf, userErr, sysErr, errCode := NewInfo(r, nil, nil)
 		if userErr != nil || sysErr != nil {
@@ -151,7 +160,15 @@ func UpdateHandler(obj Updater) http.HandlerFunc {
 		}
 		defer inf.Close()
 
+		interfacePtr := reflect.ValueOf(updater)
+		if interfacePtr.Kind() != reflect.Ptr {
+			HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("reflect: can only indirect from a pointer"))
+			return
+		}
+		objectType := reflect.Indirect(interfacePtr).Type()
+		obj := reflect.New(objectType).Interface().(Updater)
 		obj.SetInfo(inf)
+
 		if err := decodeAndValidateRequestBody(r, obj); err != nil {
 			HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, err, nil)
 			return
@@ -221,7 +238,7 @@ func UpdateHandler(obj Updater) http.HandlerFunc {
 //   *current user
 //   *change log entry
 //   *forming and writing the body over the wire
-func DeleteHandler(obj Deleter) http.HandlerFunc {
+func DeleteHandler(deleter Deleter) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 		inf, userErr, sysErr, errCode := NewInfo(r, nil, nil)
 		if userErr != nil || sysErr != nil {
@@ -230,7 +247,15 @@ func DeleteHandler(obj Deleter) http.HandlerFunc {
 		}
 		defer inf.Close()
 
+		interfacePtr := reflect.ValueOf(deleter)
+		if interfacePtr.Kind() != reflect.Ptr {
+			HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("reflect: can only indirect from a pointer"))
+			return
+		}
+		objectType := reflect.Indirect(interfacePtr).Type()
+		obj := reflect.New(objectType).Interface().(Deleter)
 		obj.SetInfo(inf)
+
 		keyFields := obj.GetKeyFieldsInfo() // expecting a slice of the key fields info which is a struct with the field name and a function to convert a string into a interface{} of the right type. in most that will be [{Field:"id",Func: func(s string)(interface{},error){return strconv.Atoi(s)}}]
 		keys := make(map[string]interface{})
 		for _, kf := range keyFields {
@@ -282,7 +307,7 @@ func DeleteHandler(obj Deleter) http.HandlerFunc {
 //   *decoding and validating the struct
 //   *change log entry
 //   *forming and writing the body over the wire
-func CreateHandler(obj Creator) http.HandlerFunc {
+func CreateHandler(creator Creator) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 		inf, userErr, sysErr, errCode := NewInfo(r, nil, nil)
 		if userErr != nil || sysErr != nil {
@@ -291,7 +316,15 @@ func CreateHandler(obj Creator) http.HandlerFunc {
 		}
 		defer inf.Close()
 
+		interfacePtr := reflect.ValueOf(creator)
+		if interfacePtr.Kind() != reflect.Ptr {
+			HandleErr(w, r, inf.Tx.Tx, http.StatusInternalServerError, nil, errors.New("reflect: can only indirect from a pointer"))
+			return
+		}
+		objectType := reflect.Indirect(interfacePtr).Type()
+		obj := reflect.New(objectType).Interface().(Creator)
 		obj.SetInfo(inf)
+
 		err := decodeAndValidateRequestBody(r, obj)
 		if err != nil {
 			HandleErr(w, r, inf.Tx.Tx, http.StatusBadRequest, err, nil)