-
Notifications
You must be signed in to change notification settings - Fork 7
/
http.go
144 lines (109 loc) · 3.08 KB
/
http.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package handy
import (
"encoding/json"
"log"
"net/http"
)
// HTTPRequestAsString gets a parameter coming from a http request as string, truncated to maxLength
// Only maxLength >= 1 is considered. Otherwise, it's ignored
func HTTPRequestAsString(r *http.Request, key string, maxLength int, transformOptions ...uint) string {
if err := r.ParseForm(); err != nil {
log.Println(r.RequestURI, err)
return ""
}
s := r.FormValue(key)
if s == "" {
s = r.URL.Query().Get(key)
if s == "" {
return ""
}
}
if len(transformOptions) > 0 {
s = Transform(s, maxLength, transformOptions[0])
}
if s == "" {
return ""
}
if (maxLength > 0) && (len([]rune(s)) >= maxLength) {
return s[0:maxLength]
}
return s
}
// HTTPRequestAsInteger gets a parameter coming from a http request as an integer
// It tries to guess if it's a signed/negative integer
func HTTPRequestAsInteger(r *http.Request, key string) int {
if err := r.ParseForm(); err != nil {
return 0
}
s := r.FormValue(key)
if s == "" {
s = r.URL.Query().Get(key)
if s == "" {
return 0
}
}
neg := s[0:1] == "-"
i := StringAsInteger(s)
if neg && (i > 0) {
return i * -1
}
return i
}
// HTTPRequestAsFloat64 gets a parameter coming from a http request as float64 number
// You have to inform the decimal separator symbol.
// If decimalSeparator is period, engine considers thousandSeparator is comma, and vice-versa.
func HTTPRequestAsFloat64(r *http.Request, key string, decimalSeparator rune) float64 {
if err := r.ParseForm(); err != nil {
return 0
}
s := r.FormValue(key)
if s == "" {
s = r.URL.Query().Get(key)
if s == "" {
return 0
}
}
thousandSeparator := Tif(decimalSeparator == ',', '.', ',').(rune)
return StringAsFloat(s, decimalSeparator, thousandSeparator)
}
// HTTPJSONBodyToStruct decode json to a given anatomically compatible struct
// THIS ROUTINE IS BEEN DEPRECATED. Use HTTPJSONToStruct() instead.
func HTTPJSONBodyToStruct(r *http.Request, targetStruct interface{}) bool {
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(targetStruct)
return err == nil
}
// HTTPJSONToStruct decode json to a given anatomically compatible struct
// the differences to HTTPJSONBodyToStruct is that:
// - HTTPJSONToStruct can condittionally close body after unmarshalling
// - HTTPJSONToStruct returns an error instead of a bool
func HTTPJSONToStruct(r *http.Request, targetStruct interface{}, closeBody bool) error {
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(targetStruct)
if closeBody {
defer func() {
if err0 := r.Body.Close(); err0 != nil {
log.Println(err0)
}
}()
}
return err
}
// HTTPAnswerJSON converts the given data as json, set the content-type header and write it to requester
func HTTPAnswerJSON(w http.ResponseWriter, data interface{}) error {
var jb []byte
if j1, ok := data.(string); ok {
jb = []byte(j1)
} else {
if j2, err := json.Marshal(data); err != nil {
return err
} else {
jb = j2
}
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
if _, errw := w.Write(jb); errw != nil {
return errw
}
return nil
}