-
Notifications
You must be signed in to change notification settings - Fork 8
/
request.go
130 lines (113 loc) · 3.14 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
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
package frodo
import (
"net/http"
"strings"
)
// Request will help facilitate the passing of multiple handlers
type Request struct {
files []*UploadedFile
*http.Request
*RequestMiddleware
Params
}
// Input gets ALL key/values sent via POST from all methods.
// Keep in mind `r.Form == type url.Values map[string][]string`
func (r *Request) Input(name string) []string {
if r.Form == nil {
r.ParseForm()
}
if value, ok := r.Form[name]; ok {
return value
}
return nil
}
// HasInput checks for the existence of the given
// input name in the inputs sent from a FORM
func (r *Request) HasInput(name string) bool {
if r.Form == nil {
r.ParseForm()
}
_, ok := r.Form[name]
return ok
}
// HasFile mimics FormFile method from `http.Request`
// func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error)
func (r *Request) HasFile(name string) bool {
_, _, err := r.FormFile(name)
if err != nil {
return false
}
return true
}
// UploadedFile gets the file requested that was uploaded
func (r *Request) UploadedFile(name string) (*UploadedFile, error) {
file, header, err := r.FormFile(name)
if err == nil {
return &UploadedFile{file, header}, nil
}
return nil, err
}
// UploadedFiles parses all uploaded files, creates and returns an array of UploadedFile
// type representing each uploaded file
func (r *Request) UploadedFiles(name string) []*UploadedFile {
// Instantiate r.files
if r.files == nil {
r.files = make([]*UploadedFile, len(r.MultipartForm.File[name]))
r.ParseMultipartForm(32 << 20)
}
for _, header := range r.MultipartForm.File[name] {
file, _ := header.Open()
r.files = append(r.files, &UploadedFile{file, header})
}
return r.files
}
// MoveAll is a neat trick to upload all the files that
// have been parsed. Awesome for bulk uploading, and storage.
func (r *Request) MoveAll(args ...interface{}) (bool, int) {
if r.files == nil {
return false, 0
}
count := 0
for _, file := range r.files {
moved := file.Move(args...)
if moved {
count++
}
}
if count == len(r.files) {
return true, count
}
return false, count
}
// ClientIP implements a best effort algorithm to return the real client IP, it parses
// X-Real-IP and X-Forwarded-For in order to work properly with reverse-proxies such us: nginx or haproxy.
func (r *Request) ClientIP() string {
if true {
clientIP := strings.TrimSpace(r.Request.Header.Get("X-Real-Ip"))
if len(clientIP) > 0 {
return clientIP
}
clientIP = r.Request.Header.Get("X-Forwarded-For")
if index := strings.IndexByte(clientIP, ','); index >= 0 {
clientIP = clientIP[0:index]
}
clientIP = strings.TrimSpace(clientIP)
if len(clientIP) > 0 {
return clientIP
}
}
return strings.TrimSpace(r.Request.RemoteAddr)
}
// IsAjax checks if the Request was made via AJAX,
// the XMLHttpRequest will usually be sent with a X-Requested-With HTTP header.
func (r *Request) IsAjax() bool {
if r.Request.Header.Get("X-Request-With") != "" {
return true
}
return false
}
// IsXhr gives user a choice in whichever way he/she feels okay checking for AJAX Request
// It actually calls r.IsAjax()
func (r *Request) IsXhr() bool {
return r.IsAjax()
}