summaryrefslogtreecommitdiff
path: root/pkg/api/handlers/decoder.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/api/handlers/decoder.go')
-rw-r--r--pkg/api/handlers/decoder.go91
1 files changed, 91 insertions, 0 deletions
diff --git a/pkg/api/handlers/decoder.go b/pkg/api/handlers/decoder.go
new file mode 100644
index 000000000..890d77ecc
--- /dev/null
+++ b/pkg/api/handlers/decoder.go
@@ -0,0 +1,91 @@
+package handlers
+
+import (
+ "encoding/json"
+ "reflect"
+ "time"
+
+ "github.com/gorilla/schema"
+ "github.com/sirupsen/logrus"
+)
+
+// NewAPIDecoder returns a configured schema.Decoder
+func NewAPIDecoder() *schema.Decoder {
+ _ = ParseDateTime
+
+ d := schema.NewDecoder()
+ d.IgnoreUnknownKeys(true)
+ d.RegisterConverter(map[string][]string{}, convertUrlValuesString)
+ d.RegisterConverter(time.Time{}, convertTimeString)
+ return d
+}
+
+// On client:
+// v := map[string][]string{
+// "dangling": {"true"},
+// }
+//
+// payload, err := jsoniter.MarshalToString(v)
+// if err != nil {
+// panic(err)
+// }
+// payload = url.QueryEscape(payload)
+func convertUrlValuesString(query string) reflect.Value {
+ f := map[string][]string{}
+
+ err := json.Unmarshal([]byte(query), &f)
+ if err != nil {
+ logrus.Infof("convertUrlValuesString: Failed to Unmarshal %s: %s", query, err.Error())
+ }
+
+ return reflect.ValueOf(f)
+}
+
+// isZero() can be used to determine if parsing failed.
+func convertTimeString(query string) reflect.Value {
+ var (
+ err error
+ t time.Time
+ )
+
+ for _, f := range []string{
+ time.UnixDate,
+ time.ANSIC,
+ time.RFC1123,
+ time.RFC1123Z,
+ time.RFC3339,
+ time.RFC3339Nano,
+ time.RFC822,
+ time.RFC822Z,
+ time.RFC850,
+ time.RubyDate,
+ time.Stamp,
+ time.StampMicro,
+ time.StampMilli,
+ time.StampNano,
+ } {
+ t, err = time.Parse(f, query)
+ if err == nil {
+ return reflect.ValueOf(t)
+ }
+
+ if _, isParseError := err.(*time.ParseError); isParseError {
+ // Try next format
+ continue
+ } else {
+ break
+ }
+ }
+
+ // We've exhausted all formats, or something bad happened
+ if err != nil {
+ logrus.Infof("convertTimeString: Failed to parse %s: %s", query, err.Error())
+ }
+ return reflect.ValueOf(time.Time{})
+}
+
+// ParseDateTime is a helper function to aid in parsing different Time/Date formats
+// isZero() can be used to determine if parsing failed.
+func ParseDateTime(query string) time.Time {
+ return convertTimeString(query).Interface().(time.Time)
+}