forked from redneckbeard/gadget
/
request.go
103 lines (92 loc) · 2.46 KB
/
request.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
package gadget
import (
"encoding/json"
"fmt"
"github.com/redneckbeard/gadget/env"
"io/ioutil"
"net/http"
"strings"
"time"
)
type DebugChecker func(*Request) bool
var SetDebugWith DebugChecker = func(r *Request) bool { return false }
// Request wraps an *http.Request and adds some Gadget-derived conveniences. The
// Params map contains either POST data, GET query parameters, or the body of the
// request deserialized as JSON if the request sends an Accept header of
// application/json. The UrlParams map contains any resource ids plucked from the
// URL by the router. The User is either an AnonymousUser or an object returned by
// the UserIdentifier that the application as registered with IdentifyUsersWith.
type Request struct {
*http.Request
Params map[string]interface{}
Path string
UrlParams map[string]string
User User
}
func newRequest(raw *http.Request) *Request {
r := &Request{Request: raw, Path: raw.URL.Path[1:]}
r.setParams()
return r
}
func (r *Request) ContentType() string {
accept := r.Request.Header.Get("Accept")
if accept != "" {
return accept
}
return r.Request.Header.Get("Content-Type")
}
func (r *Request) Debug() bool {
return env.Debug || SetDebugWith(r)
}
func unpackValues(params map[string]interface{}, values map[string][]string) {
for k, v := range values {
if len(v) == 1 {
params[k] = v[0]
} else {
params[k] = v
}
}
}
func (r *Request) setParams() {
params := make(map[string]interface{})
switch ct := r.Request.Header.Get("Content-Type"); {
case ct == "application/json":
if r.Request.Body != nil {
raw, err := ioutil.ReadAll(r.Request.Body)
defer r.Request.Body.Close()
if err != nil {
return
}
err = json.Unmarshal(raw, ¶ms)
if err != nil {
env.Log("Unable to deserialize JSON payload: ", err, string(raw))
return
}
}
case strings.HasPrefix(ct, "multipart/form-data"):
err := r.ParseMultipartForm(10 * 1024 * 1024)
if err != nil {
return
}
unpackValues(params, r.MultipartForm.Value)
default:
err := r.ParseForm()
if err != nil {
return
}
unpackValues(params, r.Form)
}
r.Params = params
}
func (r *Request) setUser() error {
if identifyUser != nil {
r.User = identifyUser(r)
} else {
r.User = &AnonymousUser{}
}
return nil
}
func (r *Request) log(status, contentLength int) {
raw := r.Request
env.Log(fmt.Sprintf(`[%s] "%s %s %s" %d %d`, time.Now().Format(time.RFC822), r.Method, raw.URL.Path, raw.Proto, status, contentLength))
}