forked from tolexo/aqua
-
Notifications
You must be signed in to change notification settings - Fork 0
/
serving.go
129 lines (121 loc) · 3.92 KB
/
serving.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package aqua
import (
"fmt"
"net/http"
"reflect"
"strconv"
"strings"
"github.com/mayur-tolexo/aero/ds"
"github.com/mayur-tolexo/aero/refl"
)
func writeOutput(w http.ResponseWriter, r *http.Request, signs []string, vals []reflect.Value, pretty string) {
if len(signs) == 1 {
if signs[0] == "int" {
w.WriteHeader(int(vals[0].Int()))
} else {
writeItem(w, r, signs[0], vals[0], pretty)
}
} else if len(signs) == 2 {
if signs[0] == "int" {
// first thing would be an integer (http status code)
w.WriteHeader(int(vals[0].Int()))
// second be the payload
writeItem(w, r, signs[1], vals[1], pretty)
} else if signs[1] == "i:.error" {
if vals[1].IsNil() {
writeItem(w, r, signs[0], vals[0], pretty)
} else {
writeItem(w, r, signs[1], vals[1], pretty)
}
} else {
panic("unsupported format")
}
}
}
func writeItem(w http.ResponseWriter, r *http.Request, sign string, val reflect.Value, pretty string) {
// Dereference a pointer to a struct or slice
if strings.HasPrefix(sign, "*st:") || strings.HasPrefix(sign, "*sl:") {
o := val.Elem()
writeItem(w, r, refl.TypeSignature(o.Type()), o, pretty)
return
}
switch {
case sign == "string":
//fmt.Printf("Sign:%s, SignDynamic:%s, Val:%s, Val.I{}:%s, Val.String():%s", sign, getSignOfObject(val.Interface()), val, val.Interface(), val.String())
v := val.Interface().(string)
w.Header().Set("Content-Type", "text/plain")
w.Header().Set("Content-Length", strconv.Itoa(len(v)))
fmt.Fprintf(w, "%s", v)
case sign == "st:"+currentRepo+".Fault":
f := val.Interface().(Fault)
j, err := ds.ToBytes(f, pretty == "true" || pretty == "1")
if err != nil {
panic(err)
}
if f.HTTPCode != 0 {
w.WriteHeader(f.HTTPCode)
} else {
// 417: Expectation failed
switch r.Method {
case "GET":
w.WriteHeader(404)
case "POST":
w.WriteHeader(417)
case "DELETE":
w.WriteHeader(417)
case "PUT":
w.WriteHeader(444) // TODO: change
default:
panic(fmt.Sprintf("Status code missing for method: %", r.Method))
}
}
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Content-Length", strconv.Itoa(len(j)))
w.Write(j)
case isError(val.Interface()) || sign == "i:.error":
if val.IsNil() {
m := map[string]interface{}{"success": 1}
writeItem(w, r, refl.ObjSignature(m), reflect.ValueOf(m), pretty)
} else {
f, ok := val.Interface().(Fault)
if !ok {
f = Fault{
Message: "Oops! An error occurred",
Issue: val.Interface().(error),
}
}
writeItem(w, r, refl.ObjSignature(f), reflect.ValueOf(f), pretty)
}
case sign == "map":
j, _ := ds.ToBytes(val.Interface(), pretty == "true" || pretty == "1")
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Content-Length", strconv.Itoa(len(j)))
w.Write(j)
case strings.HasPrefix(sign, "st:"):
j, _ := ds.ToBytes(val.Interface(), pretty == "true" || pretty == "1")
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Content-Length", strconv.Itoa(len(j)))
w.Write(j)
case strings.HasPrefix(sign, "sl:"), strings.HasPrefix(sign, "ar:"):
j, _ := ds.ToBytes(val.Interface(), pretty == "true" || pretty == "1")
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Content-Length", strconv.Itoa(len(j)))
w.Write(j)
case sign == "i:.":
writeItem(w, r, refl.ObjSignature(val.Interface()), val, pretty)
// fmt.Println("interface{} resolves to:", getSignOfObject(val.Interface()))
//TODO: error handling in case the returned object is an error
//TODO: along with int, xx, also support xx, error as a function
// case sign == "bool":
// i := 0
// if val.Bool() == true {
// i = 1
// }
// j, _ := ds.ToBytes(map[string]interface{}{"success": i}, pretty == "true" || pretty == "1")
// w.Header().Set("Content-Type", "application/json")
// w.Header().Set("Content-Length", strconv.Itoa(len(j)))
// w.Write(j)
default:
fmt.Printf("Don't know how to %s?\n", sign)
}
}