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 <[email protected]>
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)

Reply via email to