summaryrefslogtreecommitdiff
path: root/http/data.go
diff options
context:
space:
mode:
Diffstat (limited to 'http/data.go')
-rw-r--r--http/data.go67
1 files changed, 67 insertions, 0 deletions
diff --git a/http/data.go b/http/data.go
new file mode 100644
index 00000000..865e4760
--- /dev/null
+++ b/http/data.go
@@ -0,0 +1,67 @@
+package http
+
+import (
+ "strings"
+ "net/http"
+)
+
+const maxLevel = 127
+
+type dataTree map[string]interface{}
+
+// parsePost parses incoming request body into data tree.
+func parsePost(r *http.Request) (dataTree, error) {
+ data := make(dataTree)
+
+ for k, v := range r.PostForm {
+ data.push(k, v)
+ }
+
+ for k, v := range r.MultipartForm.Value {
+ data.push(k, v)
+ }
+
+ return data, nil
+}
+
+func (d dataTree) push(k string, v []string) {
+ if len(v) == 0 {
+ // skip empty values
+ return
+ }
+
+ indexes := make([]string, 0)
+ for _, index := range strings.Split(k, "[") {
+ indexes = append(indexes, strings.Trim(index, "]"))
+ }
+
+ if len(indexes) <= maxLevel {
+ d.mount(indexes, v)
+ }
+}
+
+// mount mounts data tree recursively.
+func (d dataTree) mount(i []string, v []string) {
+ if len(v) == 0 || v[0] == "" {
+ return
+ }
+
+ if len(i) == 1 {
+ // single value context
+ d[i[0]] = v[0]
+ return
+ }
+
+ if len(i) == 2 && i[1] == "" {
+ // non associated array of elements
+ d[i[0]] = v
+ return
+ }
+
+ if p, ok := d[i[0]]; ok {
+ p.(dataTree).mount(i[1:], v)
+ }
+
+ d[i[0]] = make(dataTree)
+ d[i[0]].(dataTree).mount(i[1:], v)
+}