Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 14, 05:15 UTC
admin: POST /... expands and appends all array elements
Makes it easy to append many items to an array in one command
Matthew Holt committed
Dec 17, 2019 at 10:11 UTC
6455efa5d327377b41e708a063d1b7a71a131165
2 files changed
+39
-6
admin.go
+33
-6
@@ -636,6 +636,19 @@ func unsyncedConfigAccess(method, path string, body []byte, out io.Writer) error
636
return fmt.Errorf("path missing")
637
}
638
639
+ // A path that ends with "..." implies:
640
+ // 1) the part before it is an array
641
+ // 2) the payload is an array
642
+ // and means that the user wants to expand the elements
643
+ // in the payload array and append each one into the
644
+ // destination array, like so:
645
+ // array = append(array, elems...)
646
+ // This special case is handled below.
647
+ ellipses := parts[len(parts)-1] == "..."
648
+ if ellipses {
649
+ parts = parts[:len(parts)-1]
650
+ }
651
+
652
var ptr interface{} = rawCfg
653
654
traverseLoop:
@@ -666,7 +679,15 @@ traverseLoop:
679
return fmt.Errorf("encoding config: %v", err)
680
}
681
case http.MethodPost:
669
- v[part] = append(arr, val)
682
+ if ellipses {
683
+ valArray, ok := val.([]interface{})
684
+ if !ok {
685
+ return fmt.Errorf("final element is not an array")
686
+ }
687
+ v[part] = append(arr, valArray...)
688
+ } else {
689
+ v[part] = append(arr, val)
690
+ }
691
case http.MethodPut:
692
// avoid creation of new slice and a second copy (see
693
// https://github.com/golang/go/wiki/SliceTricks#insert)
@@ -692,13 +713,19 @@ traverseLoop:
713
return fmt.Errorf("encoding config: %v", err)
714
}
715
case http.MethodPost:
716
+ // if the part is an existing list, POST appends to
717
+ // it, otherwise it just sets or creates the value
718
if arr, ok := v[part].([]interface{}); ok {
696
- // if the part is an existing list, POST appends to it
697
- // TODO: Do we ever reach this point, since we handle arrays
698
- // separately above?
699
- v[part] = append(arr, val)
719
+ if ellipses {
720
+ valArray, ok := val.([]interface{})
721
+ if !ok {
722
+ return fmt.Errorf("final element is not an array")
723
+ }
724
+ v[part] = append(arr, valArray...)
725
+ } else {
726
+ v[part] = append(arr, val)
727
+ }
728
} else {
701
- // otherwise, it simply sets the value
729
v[part] = val
730
}
731
case http.MethodPut:
admin_test.go
+6
@@ -77,6 +77,12 @@ func TestUnsyncedConfigAccess(t *testing.T) {
77
payload: `"d"`,
78
expect: `{"foo": "jet", "bar": {"aa": "bb"}, "list": ["a", "b", "c", "d"]}`,
79
},
80
+ {
81
+ method: "POST",
82
+ path: "/list/...",
83
+ payload: `["e", "f", "g"]`,
84
+ expect: `{"foo": "jet", "bar": {"aa": "bb"}, "list": ["a", "b", "c", "d", "e", "f", "g"]}`,
85
+ },
86
} {
87
err := unsyncedConfigAccess(tc.method, rawConfigKey+tc.path, []byte(tc.payload), nil)
88