github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/pkg/api/handlers/decoder.go (about) 1 package handlers 2 3 import ( 4 "encoding/json" 5 "reflect" 6 "syscall" 7 "time" 8 9 "github.com/containers/podman/v2/pkg/util" 10 "github.com/gorilla/schema" 11 "github.com/sirupsen/logrus" 12 ) 13 14 // NewAPIDecoder returns a configured schema.Decoder 15 func NewAPIDecoder() *schema.Decoder { 16 _ = ParseDateTime 17 18 d := schema.NewDecoder() 19 d.IgnoreUnknownKeys(true) 20 d.RegisterConverter(map[string][]string{}, convertURLValuesString) 21 d.RegisterConverter(time.Time{}, convertTimeString) 22 23 var Signal syscall.Signal 24 d.RegisterConverter(Signal, convertSignal) 25 return d 26 } 27 28 // On client: 29 // v := map[string][]string{ 30 // "dangling": {"true"}, 31 // } 32 // 33 // payload, err := jsoniter.MarshalToString(v) 34 // if err != nil { 35 // panic(err) 36 // } 37 // payload = url.QueryEscape(payload) 38 func convertURLValuesString(query string) reflect.Value { 39 f := map[string][]string{} 40 41 err := json.Unmarshal([]byte(query), &f) 42 if err != nil { 43 logrus.Infof("convertURLValuesString: Failed to Unmarshal %s: %s", query, err.Error()) 44 } 45 46 return reflect.ValueOf(f) 47 } 48 49 // isZero() can be used to determine if parsing failed. 50 func convertTimeString(query string) reflect.Value { 51 var ( 52 err error 53 t time.Time 54 ) 55 56 for _, f := range []string{ 57 time.UnixDate, 58 time.ANSIC, 59 time.RFC1123, 60 time.RFC1123Z, 61 time.RFC3339, 62 time.RFC3339Nano, 63 time.RFC822, 64 time.RFC822Z, 65 time.RFC850, 66 time.RubyDate, 67 time.Stamp, 68 time.StampMicro, 69 time.StampMilli, 70 time.StampNano, 71 } { 72 t, err = time.Parse(f, query) 73 if err == nil { 74 return reflect.ValueOf(t) 75 } 76 77 if _, isParseError := err.(*time.ParseError); isParseError { 78 // Try next format 79 continue 80 } else { 81 break 82 } 83 } 84 85 // We've exhausted all formats, or something bad happened 86 if err != nil { 87 logrus.Infof("convertTimeString: Failed to parse %s: %s", query, err.Error()) 88 } 89 return reflect.ValueOf(time.Time{}) 90 } 91 92 // ParseDateTime is a helper function to aid in parsing different Time/Date formats 93 // isZero() can be used to determine if parsing failed. 94 func ParseDateTime(query string) time.Time { 95 return convertTimeString(query).Interface().(time.Time) 96 } 97 98 func convertSignal(query string) reflect.Value { 99 signal, err := util.ParseSignal(query) 100 if err != nil { 101 logrus.Infof("convertSignal: Failed to parse %s: %s", query, err.Error()) 102 } 103 return reflect.ValueOf(signal) 104 }