mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-16 21:56:40 -05:00
admin: POST /... expands and appends all array elements
Makes it easy to append many items to an array in one command
This commit is contained in:
parent
5ab17a3a37
commit
6455efa5d3
2 changed files with 39 additions and 6 deletions
39
admin.go
39
admin.go
|
@ -636,6 +636,19 @@ func unsyncedConfigAccess(method, path string, body []byte, out io.Writer) error
|
|||
return fmt.Errorf("path missing")
|
||||
}
|
||||
|
||||
// A path that ends with "..." implies:
|
||||
// 1) the part before it is an array
|
||||
// 2) the payload is an array
|
||||
// and means that the user wants to expand the elements
|
||||
// in the payload array and append each one into the
|
||||
// destination array, like so:
|
||||
// array = append(array, elems...)
|
||||
// This special case is handled below.
|
||||
ellipses := parts[len(parts)-1] == "..."
|
||||
if ellipses {
|
||||
parts = parts[:len(parts)-1]
|
||||
}
|
||||
|
||||
var ptr interface{} = rawCfg
|
||||
|
||||
traverseLoop:
|
||||
|
@ -666,7 +679,15 @@ traverseLoop:
|
|||
return fmt.Errorf("encoding config: %v", err)
|
||||
}
|
||||
case http.MethodPost:
|
||||
v[part] = append(arr, val)
|
||||
if ellipses {
|
||||
valArray, ok := val.([]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("final element is not an array")
|
||||
}
|
||||
v[part] = append(arr, valArray...)
|
||||
} else {
|
||||
v[part] = append(arr, val)
|
||||
}
|
||||
case http.MethodPut:
|
||||
// avoid creation of new slice and a second copy (see
|
||||
// https://github.com/golang/go/wiki/SliceTricks#insert)
|
||||
|
@ -692,13 +713,19 @@ traverseLoop:
|
|||
return fmt.Errorf("encoding config: %v", err)
|
||||
}
|
||||
case http.MethodPost:
|
||||
// if the part is an existing list, POST appends to
|
||||
// it, otherwise it just sets or creates the value
|
||||
if arr, ok := v[part].([]interface{}); ok {
|
||||
// if the part is an existing list, POST appends to it
|
||||
// TODO: Do we ever reach this point, since we handle arrays
|
||||
// separately above?
|
||||
v[part] = append(arr, val)
|
||||
if ellipses {
|
||||
valArray, ok := val.([]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("final element is not an array")
|
||||
}
|
||||
v[part] = append(arr, valArray...)
|
||||
} else {
|
||||
v[part] = append(arr, val)
|
||||
}
|
||||
} else {
|
||||
// otherwise, it simply sets the value
|
||||
v[part] = val
|
||||
}
|
||||
case http.MethodPut:
|
||||
|
|
|
@ -77,6 +77,12 @@ func TestUnsyncedConfigAccess(t *testing.T) {
|
|||
payload: `"d"`,
|
||||
expect: `{"foo": "jet", "bar": {"aa": "bb"}, "list": ["a", "b", "c", "d"]}`,
|
||||
},
|
||||
{
|
||||
method: "POST",
|
||||
path: "/list/...",
|
||||
payload: `["e", "f", "g"]`,
|
||||
expect: `{"foo": "jet", "bar": {"aa": "bb"}, "list": ["a", "b", "c", "d", "e", "f", "g"]}`,
|
||||
},
|
||||
} {
|
||||
err := unsyncedConfigAccess(tc.method, rawConfigKey+tc.path, []byte(tc.payload), nil)
|
||||
|
||||
|
|
Loading…
Reference in a new issue